# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
# pylint: skip-file
"""Console key bindings."""
import logging
from typing import Dict, List

from prompt_toolkit.filters import (
    Condition,
    has_focus,
)
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous
from prompt_toolkit.key_binding.key_bindings import Binding

import pw_console.pw_ptpython_repl

__all__ = ('create_key_bindings', )

_LOG = logging.getLogger(__package__)

DEFAULT_KEY_BINDINGS: Dict[str, List[str]] = {
    'global.open-user-guide': ['f1'],
    'global.open-menu-search': ['c-p'],
    'global.focus-previous-widget': ['c-left'],
    'global.focus-next-widget': ['c-right', 's-tab'],
    'global.exit-no-confirmation': ['c-x c-c'],
    'global.exit-with-confirmation': ['c-d'],
    'log-pane.shift-line-to-top': ['z t'],
    'log-pane.shift-line-to-center': ['z z'],
    'log-pane.toggle-follow': ['f'],
    'log-pane.toggle-wrap-lines': ['w'],
    'log-pane.toggle-table-view': ['t'],
    'log-pane.duplicate-log-pane': ['insert'],
    'log-pane.remove-duplicated-log-pane': ['delete'],
    'log-pane.clear-history': ['C'],
    'log-pane.toggle-follow': ['f'],
    'log-pane.move-cursor-up': ['up', 'k'],
    'log-pane.move-cursor-down': ['down', 'j'],
    'log-pane.visual-select-up': ['s-up'],
    'log-pane.visual-select-down': ['s-down'],
    'log-pane.visual-select-all': ['N', 'c-r'],
    'log-pane.deselect-cancel-search': ['c-c'],
    'log-pane.scroll-page-up': ['pageup'],
    'log-pane.scroll-page-down': ['pagedown'],
    'log-pane.scroll-to-top': ['g'],
    'log-pane.scroll-to-bottom': ['G'],
    'log-pane.save-copy': ['c-o'],
    'log-pane.search': ['/', 'c-f'],
    'log-pane.search-next-match': ['n', 'c-s', 'c-g'],
    'log-pane.search-previous-match': ['N', 'c-r'],
    'log-pane.search-apply-filter': ['escape c-f'],
    'log-pane.clear-filters': ['escape c-r'],
    'search-toolbar.toggle-column': ['c-t'],
    'search-toolbar.toggle-invert': ['c-v'],
    'search-toolbar.toggle-matcher': ['c-n'],
    'search-toolbar.cancel': ['escape', 'c-c', 'c-d'],
    'search-toolbar.create-filter': ['escape c-f'],
    'window-manager.move-pane-left': ['escape c-left'],  # Alt-Ctrl-
    'window-manager.move-pane-right': ['escape c-right'],  # Alt-Ctrl-
    # NOTE: c-up and c-down seem swapped in prompt-toolkit
    'window-manager.move-pane-down': ['escape c-up'],  # Alt-Ctrl-
    'window-manager.move-pane-up': ['escape c-down'],  # Alt-Ctrl-
    'window-manager.enlarge-pane': ['escape ='],  # Alt-= (mnemonic: Alt Plus)
    'window-manager.shrink-pane':
    ['escape -'],  # Alt-minus (mnemonic: Alt Minus)
    'window-manager.shrink-split': ['escape ,'],  # Alt-, (mnemonic: Alt <)
    'window-manager.enlarge-split': ['escape .'],  # Alt-. (mnemonic: Alt >)
    'window-manager.focus-prev-pane': ['escape c-p'],  # Ctrl-Alt-p
    'window-manager.focus-next-pane': ['escape c-n'],  # Ctrl-Alt-n
    'window-manager.balance-window-panes': ['c-u'],
    'python-repl.copy-output-selection': ['c-c'],
    'python-repl.copy-all-output': ['escape c-c'],
    'python-repl.copy-clear-or-cancel': ['c-c'],
    'python-repl.paste-to-input': ['c-v'],
    'save-as-dialog.cancel': ['escape', 'c-c', 'c-d'],
    'quit-dialog.no': ['escape', 'n', 'c-c'],
    'quit-dialog.yes': ['y', 'c-d'],
    'command-runner.cancel': ['escape', 'c-c'],
    'command-runner.select-previous-item': ['up', 's-tab'],
    'command-runner.select-next-item': ['down', 'tab'],
    'help-window.close': ['q', 'f1', 'escape'],
    'help-window.copy-all': ['c-c'],
}


def create_key_bindings(console_app) -> KeyBindings:
    """Create custom key bindings.

    This starts with the key bindings, defined by `prompt-toolkit`, but adds the
    ones which are specific for the console_app. A console_app instance
    reference is passed in so key bind functions can access it.
    """

    key_bindings = KeyBindings()
    register = console_app.prefs.register_keybinding

    @register('global.open-user-guide',
              key_bindings,
              filter=Condition(lambda: not console_app.modal_window_is_open()))
    def show_help(event):
        """Toggle user guide window."""
        console_app.user_guide_window.toggle_display()

    # F2 is ptpython settings
    # F3 is ptpython history

    @register('global.open-menu-search',
              key_bindings,
              filter=Condition(lambda: not console_app.modal_window_is_open()))
    def show_command_runner(event):
        """Open command runner window."""
        console_app.open_command_runner_main_menu()

    @register('global.focus-previous-widget', key_bindings)
    def app_focus_previous(event):
        """Move focus to the previous widget."""
        focus_previous(event)

    @register('global.focus-next-widget', key_bindings)
    def app_focus_next(event):
        """Move focus to the next widget."""
        focus_next(event)

    # Bindings for when the ReplPane input field is in focus.
    # These are hidden from help window global keyboard shortcuts since the
    # method names end with `_hidden`.
    @register('python-repl.copy-clear-or-cancel',
              key_bindings,
              filter=has_focus(console_app.pw_ptpython_repl))
    def handle_ctrl_c_hidden(event):
        """Reset the python repl on Ctrl-c"""
        console_app.repl_pane.ctrl_c()

    @register('global.exit-no-confirmation', key_bindings)
    def quit_no_confirm(event):
        """Quit without confirmation."""
        event.app.exit()

    @register(
        'global.exit-with-confirmation',
        key_bindings,
        filter=console_app.pw_ptpython_repl.input_empty_if_in_focus_condition(
        ) | has_focus(console_app.quit_dialog))
    def quit(event):
        """Quit with confirmation dialog."""
        # If the python repl is in focus and has text input then Ctrl-d will
        # delete forward characters instead.
        console_app.quit_dialog.open_dialog()

    @register('python-repl.paste-to-input',
              key_bindings,
              filter=has_focus(console_app.pw_ptpython_repl))
    def paste_into_repl(event):
        """Reset the python repl on Ctrl-c"""
        console_app.repl_pane.paste_system_clipboard_to_input_buffer()

    @register('python-repl.copy-all-output',
              key_bindings,
              filter=console_app.repl_pane.input_or_output_has_focus())
    def copy_repl_output_text(event):
        """Copy all Python output to the system clipboard."""
        console_app.repl_pane.copy_all_output_text()

    return key_bindings
