# 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.
"""Window pane base class."""

from abc import ABC
from typing import Any, Callable, List, Optional, Tuple, TYPE_CHECKING, Union
import functools

from prompt_toolkit.layout.dimension import AnyDimension

from prompt_toolkit.filters import Condition
from prompt_toolkit.layout import (
    AnyContainer,
    ConditionalContainer,
    Dimension,
    HSplit,
    walk,
)
from prompt_toolkit.widgets import MenuItem

from pw_console.get_pw_console_app import get_pw_console_app

import pw_console.widgets.checkbox
import pw_console.widgets.mouse_handlers
import pw_console.style

if TYPE_CHECKING:
    from pw_console.console_app import ConsoleApp


class WindowPaneHSplit(HSplit):
    """PromptToolkit HSplit that saves the current width and height.

    This overrides the write_to_screen function to save the width and height of
    the container to be rendered.
    """
    def __init__(self, parent_window_pane, *args, **kwargs):
        # Save a reference to the parent window pane.
        self.parent_window_pane = parent_window_pane
        super().__init__(*args, **kwargs)

    def write_to_screen(
        self,
        screen,
        mouse_handlers,
        write_position,
        parent_style: str,
        erase_bg: bool,
        z_index: Optional[int],
    ) -> None:
        # Save the width and height for the current render pass. This will be
        # used by the log pane to render the correct amount of log lines.
        self.parent_window_pane.update_pane_size(write_position.width,
                                                 write_position.height)
        # Continue writing content to the screen.
        super().write_to_screen(screen, mouse_handlers, write_position,
                                parent_style, erase_bg, z_index)


class WindowPane(ABC):
    """The Pigweed Console Window Pane parent class."""

    # pylint: disable=too-many-instance-attributes
    def __init__(
        self,
        application: Union['ConsoleApp', Any] = None,
        pane_title: str = 'Window',
        height: Optional[AnyDimension] = None,
        width: Optional[AnyDimension] = None,
    ):
        if application:
            self.application = application
        else:
            self.application = get_pw_console_app()

        self._pane_title = pane_title
        self._pane_subtitle: str = ''

        # Default width and height to 10 lines each. They will be resized by the
        # WindowManager later.
        self.height = height if height else Dimension(preferred=10)
        self.width = width if width else Dimension(preferred=10)

        # Boolean to show or hide this window pane
        self.show_pane = True
        # Booleans for toggling top and bottom toolbars
        self.show_top_toolbar = True
        self.show_bottom_toolbar = True

        # Height and width values for the current rendering pass.
        self.current_pane_width = 0
        self.current_pane_height = 0
        self.last_pane_width = 0
        self.last_pane_height = 0

    def __repr__(self) -> str:
        """Create a repr with this pane's title and subtitle."""
        repr_str = f'{type(self).__qualname__}(pane_title="{self.pane_title()}"'
        if self.pane_subtitle():
            repr_str += f', pane_subtitle="{self.pane_subtitle()}"'
        repr_str += ')'
        return repr_str

    def pane_title(self) -> str:
        return self._pane_title

    def set_pane_title(self, title: str) -> None:
        self._pane_title = title

    def menu_title(self) -> str:
        """Return a title to display in the Window menu."""
        return self.pane_title()

    def pane_subtitle(self) -> str:  # pylint: disable=no-self-use
        """Further title info for display in the Window menu."""
        return ''

    def redraw_ui(self) -> None:
        """Redraw the prompt_toolkit UI."""
        if not hasattr(self, 'application'):
            return
        # Thread safe way of sending a repaint trigger to the input event loop.
        self.application.redraw_ui()

    def focus_self(self) -> None:
        """Switch prompt_toolkit focus to this window pane."""
        if not hasattr(self, 'application'):
            return
        self.application.focus_on_container(self)

    def __pt_container__(self):
        """Return the prompt_toolkit root container for this log pane.

        This allows self to be used wherever prompt_toolkit expects a container
        object."""
        return self.container  # pylint: disable=no-member

    def get_all_key_bindings(self) -> List:
        """Return keybinds for display in the help window.

        For example:

        Using a prompt_toolkit control:

          return [self.some_content_control_instance.get_key_bindings()]

        Hand-crafted bindings for display in the HelpWindow:

          return [{
              'Execute code': ['Enter', 'Option-Enter', 'Meta-Enter'],
              'Reverse search history': ['Ctrl-R'],
              'Erase input buffer.': ['Ctrl-C'],
              'Show settings.': ['F2'],
              'Show history.': ['F3'],
          }]
        """
        # pylint: disable=no-self-use
        return []

    def get_window_menu_options(
            self) -> List[Tuple[str, Union[Callable, None]]]:
        """Return menu options for the window pane.

        Should return a list of tuples containing with the display text and
        callable to invoke on click.
        """
        # pylint: disable=no-self-use
        return []

    def get_top_level_menus(self) -> List[MenuItem]:
        """Return MenuItems to be displayed on the main pw_console menu bar."""
        # pylint: disable=no-self-use
        return []

    def pane_resized(self) -> bool:
        """Return True if the current window size has changed."""
        return (self.last_pane_width != self.current_pane_width
                or self.last_pane_height != self.current_pane_height)

    def update_pane_size(self, width, height) -> None:
        """Save pane width and height for the current UI render pass."""
        if width:
            self.last_pane_width = self.current_pane_width
            self.current_pane_width = width
        if height:
            self.last_pane_height = self.current_pane_height
            self.current_pane_height = height

    def _create_pane_container(self, *content) -> ConditionalContainer:
        return ConditionalContainer(
            WindowPaneHSplit(
                self,
                content,
                # Window pane dimensions
                height=lambda: self.height,
                width=lambda: self.width,
                style=functools.partial(pw_console.style.get_pane_style, self),
            ),
            filter=Condition(lambda: self.show_pane))

    def has_child_container(self, child_container: AnyContainer) -> bool:
        if not child_container:
            return False
        for container in walk(self.__pt_container__()):
            if container == child_container:
                return True
        return False


class FloatingWindowPane(WindowPane):
    """The Pigweed Console FloatingWindowPane class."""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Tracks the last focused container, to enable restoring focus after
        # closing the dialog.
        self.last_focused_pane = None

    def close_dialog(self) -> None:
        """Close runner dialog box."""
        self.show_pane = False

        # Restore original focus if possible.
        if self.last_focused_pane:
            self.application.focus_on_container(self.last_focused_pane)
        else:
            # Fallback to focusing on the main menu.
            self.application.focus_main_menu()

        self.application.update_menu_items()

    def open_dialog(self) -> None:
        self.show_pane = True
        self.last_focused_pane = self.application.focused_window()
        self.focus_self()
        self.application.redraw_ui()

        self.application.update_menu_items()

    def toggle_dialog(self) -> bool:
        if self.show_pane:
            self.close_dialog()
        else:
            self.open_dialog()
        # The focused window has changed. Return true so
        # ConsoleApp.run_pane_menu_option does not set the focus to the main
        # menu.
        return True
