# 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.
"""LogPane class."""

import functools
import logging
import re
from typing import Any, List, Optional, Union, TYPE_CHECKING

from prompt_toolkit.application.current import get_app
from prompt_toolkit.filters import (
    Condition,
    has_focus,
)
from prompt_toolkit.formatted_text import StyleAndTextTuples
from prompt_toolkit.key_binding import (
    KeyBindings,
    KeyPressEvent,
    KeyBindingsBase,
)
from prompt_toolkit.layout import (
    ConditionalContainer,
    Float,
    FloatContainer,
    UIContent,
    UIControl,
    VerticalAlign,
    Window,
)
from prompt_toolkit.mouse_events import MouseEvent, MouseEventType, MouseButton

import pw_console.widgets.checkbox
import pw_console.style
from pw_console.log_view import LogView
from pw_console.log_pane_toolbars import (
    LineInfoBar,
    TableToolbar,
)
from pw_console.log_pane_saveas_dialog import LogPaneSaveAsDialog
from pw_console.log_pane_selection_dialog import LogPaneSelectionDialog
from pw_console.log_store import LogStore
from pw_console.search_toolbar import SearchToolbar
from pw_console.filter_toolbar import FilterToolbar
from pw_console.widgets import (
    ToolbarButton,
    WindowPane,
    WindowPaneHSplit,
    WindowPaneToolbar,
)

if TYPE_CHECKING:
    from pw_console.console_app import ConsoleApp

_LOG_OUTPUT_SCROLL_AMOUNT = 5
_LOG = logging.getLogger(__package__)


class LogContentControl(UIControl):
    """LogPane prompt_toolkit UIControl for displaying LogContainer lines."""
    def __init__(self, log_pane: 'LogPane') -> None:
        # pylint: disable=too-many-locals
        self.log_pane = log_pane
        self.log_view = log_pane.log_view

        # Mouse drag visual selection flags.
        self.visual_select_mode_drag_start = False
        self.visual_select_mode_drag_stop = False

        self.uicontent: Optional[UIContent] = None
        self.lines: List[StyleAndTextTuples] = []

        # Key bindings.
        key_bindings = KeyBindings()
        register = log_pane.application.prefs.register_keybinding

        @register('log-pane.shift-line-to-top', key_bindings)
        def _shift_log_to_top(_event: KeyPressEvent) -> None:
            """Shift the selected log line to the top."""
            self.log_view.move_selected_line_to_top()

        @register('log-pane.shift-line-to-center', key_bindings)
        def _shift_log_to_center(_event: KeyPressEvent) -> None:
            """Shift the selected log line to the center."""
            self.log_view.center_log_line()

        @register('log-pane.toggle-wrap-lines', key_bindings)
        def _toggle_wrap_lines(_event: KeyPressEvent) -> None:
            """Toggle log line wrapping."""
            self.log_pane.toggle_wrap_lines()

        @register('log-pane.toggle-table-view', key_bindings)
        def _toggle_table_view(_event: KeyPressEvent) -> None:
            """Toggle table view."""
            self.log_pane.toggle_table_view()

        @register('log-pane.duplicate-log-pane', key_bindings)
        def _duplicate(_event: KeyPressEvent) -> None:
            """Duplicate this log pane."""
            self.log_pane.duplicate()

        @register('log-pane.remove-duplicated-log-pane', key_bindings)
        def _delete(_event: KeyPressEvent) -> None:
            """Remove log pane."""
            if self.log_pane.is_a_duplicate:
                self.log_pane.application.window_manager.remove_pane(
                    self.log_pane)

        @register('log-pane.clear-history', key_bindings)
        def _clear_history(_event: KeyPressEvent) -> None:
            """Clear log pane history."""
            self.log_pane.clear_history()

        @register('log-pane.scroll-to-top', key_bindings)
        def _scroll_to_top(_event: KeyPressEvent) -> None:
            """Scroll to top."""
            self.log_view.scroll_to_top()

        @register('log-pane.scroll-to-bottom', key_bindings)
        def _scroll_to_bottom(_event: KeyPressEvent) -> None:
            """Scroll to bottom."""
            self.log_view.scroll_to_bottom()

        @register('log-pane.toggle-follow', key_bindings)
        def _toggle_follow(_event: KeyPressEvent) -> None:
            """Toggle log line following."""
            self.log_pane.toggle_follow()

        @register('log-pane.move-cursor-up', key_bindings)
        def _up(_event: KeyPressEvent) -> None:
            """Move cursor up."""
            self.log_view.scroll_up()

        @register('log-pane.move-cursor-down', key_bindings)
        def _down(_event: KeyPressEvent) -> None:
            """Move cursor down."""
            self.log_view.scroll_down()

        @register('log-pane.visual-select-up', key_bindings)
        def _visual_select_up(_event: KeyPressEvent) -> None:
            """Select previous log line."""
            self.log_view.visual_select_up()

        @register('log-pane.visual-select-down', key_bindings)
        def _visual_select_down(_event: KeyPressEvent) -> None:
            """Select next log line."""
            self.log_view.visual_select_down()

        @register('log-pane.scroll-page-up', key_bindings)
        def _pageup(_event: KeyPressEvent) -> None:
            """Scroll the logs up by one page."""
            self.log_view.scroll_up_one_page()

        @register('log-pane.scroll-page-down', key_bindings)
        def _pagedown(_event: KeyPressEvent) -> None:
            """Scroll the logs down by one page."""
            self.log_view.scroll_down_one_page()

        @register('log-pane.save-copy', key_bindings)
        def _start_saveas(_event: KeyPressEvent) -> None:
            """Save logs to a file."""
            self.log_pane.start_saveas()

        @register('log-pane.search', key_bindings)
        def _start_search(_event: KeyPressEvent) -> None:
            """Start searching."""
            self.log_pane.start_search()

        @register('log-pane.search-next-match', key_bindings)
        def _next_search(_event: KeyPressEvent) -> None:
            """Next search match."""
            self.log_view.search_forwards()

        @register('log-pane.search-previous-match', key_bindings)
        def _previous_search(_event: KeyPressEvent) -> None:
            """Previous search match."""
            self.log_view.search_backwards()

        @register('log-pane.visual-select-all', key_bindings)
        def _select_all_logs(_event: KeyPressEvent) -> None:
            """Clear search."""
            self.log_pane.log_view.visual_select_all()

        @register('log-pane.deselect-cancel-search', key_bindings)
        def _clear_search_and_selection(_event: KeyPressEvent) -> None:
            """Clear selection or search."""
            if self.log_pane.log_view.visual_select_mode:
                self.log_pane.log_view.clear_visual_selection()
            elif self.log_pane.search_bar_active:
                self.log_pane.search_toolbar.cancel_search()

        @register('log-pane.search-apply-filter', key_bindings)
        def _apply_filter(_event: KeyPressEvent) -> None:
            """Apply current search as a filter."""
            self.log_pane.search_toolbar.close_search_bar()
            self.log_view.apply_filter()

        @register('log-pane.clear-filters', key_bindings)
        def _clear_filter(_event: KeyPressEvent) -> None:
            """Reset / erase active filters."""
            self.log_view.clear_filters()

        self.key_bindings: KeyBindingsBase = key_bindings

    def is_focusable(self) -> bool:
        return True

    def get_key_bindings(self) -> Optional[KeyBindingsBase]:
        return self.key_bindings

    def preferred_width(self, max_available_width: int) -> int:
        """Return the width of the longest line."""
        line_lengths = [len(l) for l in self.lines]
        return max(line_lengths)

    def preferred_height(
        self,
        width: int,
        max_available_height: int,
        wrap_lines: bool,
        get_line_prefix,
    ) -> Optional[int]:
        """Return the preferred height for the log lines."""
        content = self.create_content(width, None)
        return content.line_count

    def create_content(self, width: int, height: Optional[int]) -> UIContent:
        # Update lines to render
        self.lines = self.log_view.render_content()

        # Create a UIContent instance if none exists
        if self.uicontent is None:
            self.uicontent = UIContent(get_line=lambda i: self.lines[i],
                                       line_count=len(self.lines),
                                       show_cursor=False)

        # Update line_count
        self.uicontent.line_count = len(self.lines)

        return self.uicontent

    def mouse_handler(self, mouse_event: MouseEvent):
        """Mouse handler for this control."""
        mouse_position = mouse_event.position

        # Left mouse button release should:
        # 1. check if a mouse drag just completed.
        # 2. If not in focus, switch focus to this log pane
        #    If in focus, move the cursor to that position.
        if (mouse_event.event_type == MouseEventType.MOUSE_UP
                and mouse_event.button == MouseButton.LEFT):

            # If a drag was in progress and this is the first mouse release
            # press, set the stop flag.
            if (self.visual_select_mode_drag_start
                    and not self.visual_select_mode_drag_stop):
                self.visual_select_mode_drag_stop = True

            if not has_focus(self)():
                # Focus the save as dialog if open.
                if self.log_pane.saveas_dialog_active:
                    get_app().layout.focus(self.log_pane.saveas_dialog)
                # Focus the search bar if open.
                elif self.log_pane.search_bar_active:
                    get_app().layout.focus(self.log_pane.search_toolbar)
                # Otherwise, focus on the log pane content.
                else:
                    get_app().layout.focus(self)
                # Mouse event handled, return None.
                return None

            # Log pane in focus already, move the cursor to the position of the
            # mouse click.
            self.log_pane.log_view.scroll_to_position(mouse_position)
            # Mouse event handled, return None.
            return None

        # Mouse drag with left button should start selecting lines.
        # The log pane does not need to be in focus to start this.
        if (mouse_event.event_type == MouseEventType.MOUSE_MOVE
                and mouse_event.button == MouseButton.LEFT):
            # If a previous mouse drag was completed, clear the selection.
            if (self.visual_select_mode_drag_start
                    and self.visual_select_mode_drag_stop):
                self.log_pane.log_view.clear_visual_selection()
            # Drag select in progress, set flags accordingly.
            self.visual_select_mode_drag_start = True
            self.visual_select_mode_drag_stop = False

            self.log_pane.log_view.visual_select_line(mouse_position)
            # Mouse event handled, return None.
            return None

        # Mouse wheel events should move the cursor +/- some amount of lines
        # even if this pane is not in focus.
        if mouse_event.event_type == MouseEventType.SCROLL_DOWN:
            self.log_pane.log_view.scroll_down(lines=_LOG_OUTPUT_SCROLL_AMOUNT)
            # Mouse event handled, return None.
            return None

        if mouse_event.event_type == MouseEventType.SCROLL_UP:
            self.log_pane.log_view.scroll_up(lines=_LOG_OUTPUT_SCROLL_AMOUNT)
            # Mouse event handled, return None.
            return None

        # Mouse event not handled, return NotImplemented.
        return NotImplemented


class LogPane(WindowPane):
    """LogPane class."""

    # pylint: disable=too-many-instance-attributes,too-many-public-methods

    def __init__(
        self,
        application: Any,
        pane_title: str = 'Logs',
        log_store: Optional[LogStore] = None,
    ):
        super().__init__(application, pane_title)

        # TODO(tonymd): Read these settings from a project (or user) config.
        self.wrap_lines = False
        self._table_view = True
        self.is_a_duplicate = False

        # Create the log container which stores and handles incoming logs.
        self.log_view: LogView = LogView(self,
                                         self.application,
                                         log_store=log_store)

        # Log pane size variables. These are updated just befor rendering the
        # pane by the LogLineHSplit class.
        self.current_log_pane_width = 0
        self.current_log_pane_height = 0
        self.last_log_pane_width = None
        self.last_log_pane_height = None

        # Search tracking
        self.search_bar_active = False
        self.search_toolbar = SearchToolbar(self)
        self.filter_toolbar = FilterToolbar(self)

        self.saveas_dialog = LogPaneSaveAsDialog(self)
        self.saveas_dialog_active = False
        self.visual_selection_dialog = LogPaneSelectionDialog(self)

        # Table header bar, only shown if table view is active.
        self.table_header_toolbar = TableToolbar(self)

        # Create the bottom toolbar for the whole log pane.
        self.bottom_toolbar = WindowPaneToolbar(self)
        self.bottom_toolbar.add_button(
            ToolbarButton('/', 'Search', self.start_search))
        self.bottom_toolbar.add_button(
            ToolbarButton('Ctrl-o', 'Save', self.start_saveas))
        self.bottom_toolbar.add_button(
            ToolbarButton('f',
                          'Follow',
                          self.toggle_follow,
                          is_checkbox=True,
                          checked=lambda: self.log_view.follow))
        self.bottom_toolbar.add_button(
            ToolbarButton('t',
                          'Table',
                          self.toggle_table_view,
                          is_checkbox=True,
                          checked=lambda: self.table_view))
        self.bottom_toolbar.add_button(
            ToolbarButton('w',
                          'Wrap',
                          self.toggle_wrap_lines,
                          is_checkbox=True,
                          checked=lambda: self.wrap_lines))
        self.bottom_toolbar.add_button(
            ToolbarButton('C', 'Clear', self.clear_history))

        self.log_content_control = LogContentControl(self)

        self.log_display_window = Window(
            content=self.log_content_control,
            # Scrolling is handled by LogScreen
            allow_scroll_beyond_bottom=False,
            # Line wrapping is handled by LogScreen
            wrap_lines=False,
            # Selected line highlighting is handled by LogScreen
            cursorline=False,
            # Don't make the window taller to fill the parent split container.
            # Window should match the height of the log line content. This will
            # also allow the parent HSplit to justify the content to the bottom
            dont_extend_height=True,
            # Window width should be extended to make backround highlighting
            # extend to the end of the container. Otherwise backround colors
            # will only appear until the end of the log line.
            dont_extend_width=False,
            # Needed for log lines ANSI sequences that don't specify foreground
            # or background colors.
            style=functools.partial(pw_console.style.get_pane_style, self),
        )

        # Root level container
        self.container = ConditionalContainer(
            FloatContainer(
                # Horizonal split containing the log lines and the toolbar.
                WindowPaneHSplit(
                    self,  # LogPane reference
                    [
                        self.table_header_toolbar,
                        self.log_display_window,
                        self.filter_toolbar,
                        self.search_toolbar,
                        self.bottom_toolbar,
                    ],
                    # Align content with the bottom of the container.
                    align=VerticalAlign.BOTTOM,
                    height=lambda: self.height,
                    width=lambda: self.width,
                    style=functools.partial(pw_console.style.get_pane_style,
                                            self),
                ),
                floats=[
                    Float(top=0, right=0, height=1, content=LineInfoBar(self)),
                    Float(top=0,
                          right=0,
                          height=LogPaneSelectionDialog.DIALOG_HEIGHT,
                          content=self.visual_selection_dialog),
                    Float(top=3,
                          left=2,
                          right=2,
                          height=LogPaneSaveAsDialog.DIALOG_HEIGHT + 2,
                          content=self.saveas_dialog),
                ]),
            filter=Condition(lambda: self.show_pane))

    @property
    def table_view(self):
        return self._table_view

    @table_view.setter
    def table_view(self, table_view):
        self._table_view = table_view

    def menu_title(self):
        """Return the title to display in the Window menu."""
        title = self.pane_title()

        # List active filters
        if self.log_view.filtering_on:
            title += ' (FILTERS: '
            title += ' '.join([
                log_filter.pattern()
                for log_filter in self.log_view.filters.values()
            ])
            title += ')'
        return title

    def append_pane_subtitle(self, text):
        if not self._pane_subtitle:
            self._pane_subtitle = text
        else:
            self._pane_subtitle = self._pane_subtitle + ', ' + text

    def pane_subtitle(self) -> str:
        if not self._pane_subtitle:
            return ', '.join(self.log_view.log_store.channel_counts.keys())
        logger_names = self._pane_subtitle.split(', ')
        additional_text = ''
        if len(logger_names) > 1:
            additional_text = ' + {} more'.format(len(logger_names))

        return logger_names[0] + additional_text

    def start_search(self):
        """Show the search bar to begin a search."""
        # Show the search bar
        self.search_bar_active = True
        # Focus on the search bar
        self.application.focus_on_container(self.search_toolbar)

    def start_saveas(self, **export_kwargs) -> bool:
        """Show the saveas bar to begin saving logs to a file."""
        # Show the search bar
        self.saveas_dialog_active = True
        # Set export options if any
        self.saveas_dialog.set_export_options(**export_kwargs)
        # Focus on the search bar
        self.application.focus_on_container(self.saveas_dialog)
        return True

    def pane_resized(self) -> bool:
        """Return True if the current window size has changed."""
        return (self.last_log_pane_width != self.current_log_pane_width
                or self.last_log_pane_height != self.current_log_pane_height)

    def update_pane_size(self, width, height):
        """Save width and height of the log pane for the current UI render
        pass."""
        if width:
            self.last_log_pane_width = self.current_log_pane_width
            self.current_log_pane_width = width
        if height:
            # Subtract the height of the bottom toolbar
            height -= WindowPaneToolbar.TOOLBAR_HEIGHT
            if self._table_view:
                height -= TableToolbar.TOOLBAR_HEIGHT
            if self.search_bar_active:
                height -= SearchToolbar.TOOLBAR_HEIGHT
            if self.log_view.filtering_on:
                height -= FilterToolbar.TOOLBAR_HEIGHT
            self.last_log_pane_height = self.current_log_pane_height
            self.current_log_pane_height = height

    def toggle_table_view(self):
        """Enable or disable table view."""
        self._table_view = not self._table_view
        self.log_view.view_mode_changed()
        self.redraw_ui()

    def toggle_wrap_lines(self):
        """Enable or disable line wraping/truncation."""
        self.wrap_lines = not self.wrap_lines
        self.log_view.view_mode_changed()
        self.redraw_ui()

    def toggle_follow(self):
        """Enable or disable following log lines."""
        self.log_view.toggle_follow()
        self.redraw_ui()

    def clear_history(self):
        """Erase stored log lines."""
        self.log_view.clear_scrollback()
        self.redraw_ui()

    def get_all_key_bindings(self) -> List:
        """Return all keybinds for this pane."""
        # Return log content control keybindings
        return [self.log_content_control.get_key_bindings()]

    def get_all_menu_options(self) -> List:
        """Return all menu options for the log pane."""

        options = [
            # Menu separator
            ('-', None),
            (
                'Save/Export a copy',
                self.start_saveas,
            ),
            ('-', None),
            (
                '{check} Line wrapping'.format(
                    check=pw_console.widgets.checkbox.to_checkbox_text(
                        self.wrap_lines, end='')),
                self.toggle_wrap_lines,
            ),
            (
                '{check} Table view'.format(
                    check=pw_console.widgets.checkbox.to_checkbox_text(
                        self._table_view, end='')),
                self.toggle_table_view,
            ),
            (
                '{check} Follow'.format(
                    check=pw_console.widgets.checkbox.to_checkbox_text(
                        self.log_view.follow, end='')),
                self.toggle_follow,
            ),
            # Menu separator
            ('-', None),
            (
                'Clear history',
                self.clear_history,
            ),
            (
                'Duplicate pane',
                self.duplicate,
            ),
        ]
        if self.is_a_duplicate:
            options += [(
                'Remove/Delete pane',
                functools.partial(self.application.window_manager.remove_pane,
                                  self),
            )]

        # Search / Filter section
        options += [
            # Menu separator
            ('-', None),
            (
                'Hide search highlighting',
                self.log_view.disable_search_highlighting,
            ),
            (
                'Create filter from search results',
                self.log_view.apply_filter,
            ),
            (
                'Clear/Reset active filters',
                self.log_view.clear_filters,
            ),
        ]

        return options

    def apply_filters_from_config(self, window_options) -> None:
        if 'filters' not in window_options:
            return

        for field, criteria in window_options['filters'].items():
            for matcher_name, search_string in criteria.items():
                inverted = matcher_name.endswith('-inverted')
                matcher_name = re.sub(r'-inverted$', '', matcher_name)
                if field == 'all':
                    field = None
                if self.log_view.new_search(
                        search_string,
                        invert=inverted,
                        field=field,
                        search_matcher=matcher_name,
                        interactive=False,
                ):
                    self.log_view.install_new_filter()

    def create_duplicate(self) -> 'LogPane':
        """Create a duplicate of this LogView."""
        new_pane = LogPane(self.application, pane_title=self.pane_title())
        # Set the log_store
        log_store = self.log_view.log_store
        new_pane.log_view.log_store = log_store
        # Register the duplicate pane as a viewer
        log_store.register_viewer(new_pane.log_view)

        # Set any existing search state.
        new_pane.log_view.search_text = self.log_view.search_text
        new_pane.log_view.search_filter = self.log_view.search_filter
        new_pane.log_view.search_matcher = self.log_view.search_matcher
        new_pane.log_view.search_highlight = self.log_view.search_highlight

        # Mark new pane as a duplicate so it can be deleted.
        new_pane.is_a_duplicate = True
        return new_pane

    def duplicate(self) -> None:
        new_pane = self.create_duplicate()
        # Add the new pane.
        self.application.window_manager.add_pane(new_pane)

    def add_log_handler(self,
                        logger: Union[str, logging.Logger],
                        level_name: Optional[str] = None) -> None:
        """Add a log handlers to this LogPane."""

        if isinstance(logger, logging.Logger):
            logger_instance = logger
        elif isinstance(logger, str):
            logger_instance = logging.getLogger(logger)

        if level_name:
            if not hasattr(logging, level_name):
                raise Exception(f'Unknown log level: {level_name}')
            logger_instance.level = getattr(logging, level_name, logging.INFO)
        logger_instance.addHandler(self.log_view.log_store  # type: ignore
                                   )
        self.append_pane_subtitle(  # type: ignore
            logger_instance.name)
