# Copyright 2022 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 Save As Dialog."""

from __future__ import annotations
import functools
from pathlib import Path
from typing import Optional, TYPE_CHECKING

from prompt_toolkit.buffer import Buffer
from prompt_toolkit.key_binding import KeyBindings, KeyPressEvent
from prompt_toolkit.completion import PathCompleter
from prompt_toolkit.filters import Condition
from prompt_toolkit.history import InMemoryHistory
from prompt_toolkit.layout import (
    ConditionalContainer,
    FormattedTextControl,
    HSplit,
    Window,
    WindowAlign,
)
from prompt_toolkit.widgets import TextArea
from prompt_toolkit.validation import (
    ValidationError,
    Validator,
)

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

if TYPE_CHECKING:
    from pw_console.log_pane import LogPane


class PathValidator(Validator):
    """Validation of file path input."""
    def validate(self, document):
        """Check input path leads to a valid parent directory."""
        target_path = Path(document.text).expanduser()

        if not target_path.parent.exists():
            raise ValidationError(
                # Set cursor position to the end
                len(document.text),
                "Directory doesn't exist: %s" % document.text)

        if target_path.is_dir():
            raise ValidationError(
                # Set cursor position to the end
                len(document.text),
                "File input is an existing directory: %s" % document.text)


class LogPaneSaveAsDialog(ConditionalContainer):
    """Dialog box for saving logs to a file."""
    # Height of the dialog box contens in lines of text.
    DIALOG_HEIGHT = 3

    def __init__(self, log_pane: 'LogPane'):
        self.log_pane = log_pane

        self.path_validator = PathValidator()

        self._export_with_table_formatting: bool = True
        self._export_with_selected_lines_only: bool = False

        self.starting_file_path: str = str(Path.cwd())

        self.input_field = TextArea(
            prompt=[
                ('class:saveas-dialog-setting', 'File: ',
                 functools.partial(pw_console.widgets.mouse_handlers.on_click,
                                   self.focus_self))
            ],
            # Pre-fill the current working directory.
            text=self.starting_file_path,
            focusable=True,
            focus_on_click=True,
            scrollbar=False,
            multiline=False,
            height=1,
            dont_extend_height=True,
            dont_extend_width=False,
            accept_handler=self._saveas_accept_handler,
            validator=self.path_validator,
            history=InMemoryHistory(),
            completer=PathCompleter(expanduser=True),
        )

        self.input_field.buffer.cursor_position = len(self.starting_file_path)

        settings_bar_control = FormattedTextControl(
            self.get_settings_fragments)
        settings_bar_window = Window(content=settings_bar_control,
                                     height=1,
                                     align=WindowAlign.LEFT,
                                     dont_extend_width=False)

        action_bar_control = FormattedTextControl(self.get_action_fragments)
        action_bar_window = Window(content=action_bar_control,
                                   height=1,
                                   align=WindowAlign.RIGHT,
                                   dont_extend_width=False)

        # Add additional keybindings for the input_field text area.
        key_bindings = KeyBindings()
        register = self.log_pane.application.prefs.register_keybinding

        @register('save-as-dialog.cancel', key_bindings)
        def _close_saveas_dialog(_event: KeyPressEvent) -> None:
            """Close save as dialog."""
            self.close_dialog()

        self.input_field.control.key_bindings = key_bindings

        super().__init__(
            pw_console.widgets.border.create_border(
                HSplit(
                    [
                        settings_bar_window,
                        self.input_field,
                        action_bar_window,
                    ],
                    height=LogPaneSaveAsDialog.DIALOG_HEIGHT,
                    style='class:saveas-dialog',
                ),
                LogPaneSaveAsDialog.DIALOG_HEIGHT,
                border_style='class:saveas-dialog-border',
                left_margin_columns=1,
            ),
            filter=Condition(lambda: self.log_pane.saveas_dialog_active),
        )

    def focus_self(self):
        self.log_pane.application.application.layout.focus(self)

    def close_dialog(self):
        """Close this dialog."""
        self.log_pane.saveas_dialog_active = False
        self.log_pane.application.focus_on_container(self.log_pane)
        self.log_pane.redraw_ui()

    def _toggle_table_formatting(self):
        self._export_with_table_formatting = (
            not self._export_with_table_formatting)

    def _toggle_selected_lines(self):
        self._export_with_selected_lines_only = (
            not self._export_with_selected_lines_only)

    def set_export_options(self,
                           table_format: Optional[bool] = None,
                           selected_lines_only: Optional[bool] = None) -> None:
        # Allows external callers such as the line selection dialog to set
        # export format options.
        if table_format is not None:
            self._export_with_table_formatting = table_format

        if selected_lines_only is not None:
            self._export_with_selected_lines_only = selected_lines_only

    def save_action(self):
        """Trigger save file execution on mouse click.

        This ultimately runs LogPaneSaveAsDialog._saveas_accept_handler()."""
        self.input_field.buffer.validate_and_handle()

    def _saveas_accept_handler(self, buff: Buffer) -> bool:
        """Function run when hitting Enter in the input_field."""
        input_text = buff.text
        if len(input_text) == 0:
            self.close_dialog()
            # Don't save anything if empty input.
            return False

        if self.log_pane.log_view.export_logs(
                file_name=input_text,
                use_table_formatting=self._export_with_table_formatting,
                selected_lines_only=self._export_with_selected_lines_only):
            self.close_dialog()
            # Reset selected_lines_only
            self.set_export_options(selected_lines_only=False)
            # Erase existing input text.
            return False

        # Keep existing text if error
        return True

    def get_settings_fragments(self):
        """Return FormattedText with current save settings."""
        # Mouse handlers
        focus = functools.partial(pw_console.widgets.mouse_handlers.on_click,
                                  self.focus_self)
        toggle_table_formatting = functools.partial(
            pw_console.widgets.mouse_handlers.on_click,
            self._toggle_table_formatting)
        toggle_selected_lines = functools.partial(
            pw_console.widgets.mouse_handlers.on_click,
            self._toggle_selected_lines)

        # Separator should have the focus mouse handler so clicking on any
        # whitespace focuses the input field.
        separator_text = ('', '  ', focus)

        # Default button style
        button_style = 'class:toolbar-button-inactive'

        fragments = [('class:saveas-dialog-title', 'Save as File', focus)]
        fragments.append(separator_text)

        # Table checkbox
        fragments.extend(
            pw_console.widgets.checkbox.to_checkbox_with_keybind_indicator(
                checked=self._export_with_table_formatting,
                key='',  # No key shortcut help text
                description='Table Formatting',
                mouse_handler=toggle_table_formatting,
                base_style=button_style))

        # Two space separator
        fragments.append(separator_text)

        # Selected lines checkbox
        fragments.extend(
            pw_console.widgets.checkbox.to_checkbox_with_keybind_indicator(
                checked=self._export_with_selected_lines_only,
                key='',  # No key shortcut help text
                description='Selected Lines Only',
                mouse_handler=toggle_selected_lines,
                base_style=button_style))

        # Two space separator
        fragments.append(separator_text)

        return fragments

    def get_action_fragments(self):
        """Return FormattedText with the save action buttons."""
        # Mouse handlers
        focus = functools.partial(pw_console.widgets.mouse_handlers.on_click,
                                  self.focus_self)
        cancel = functools.partial(pw_console.widgets.mouse_handlers.on_click,
                                   self.close_dialog)
        save = functools.partial(pw_console.widgets.mouse_handlers.on_click,
                                 self.save_action)

        # Separator should have the focus mouse handler so clicking on any
        # whitespace focuses the input field.
        separator_text = ('', '  ', focus)

        # Default button style
        button_style = 'class:toolbar-button-inactive'

        fragments = [separator_text]
        # Cancel button
        fragments.extend(
            pw_console.widgets.checkbox.to_keybind_indicator(
                key='Ctrl-c',
                description='Cancel',
                mouse_handler=cancel,
                base_style=button_style,
            ))

        # Two space separator
        fragments.append(separator_text)

        # Save button
        fragments.extend(
            pw_console.widgets.checkbox.to_keybind_indicator(
                key='Enter',
                description='Save',
                mouse_handler=save,
                base_style=button_style,
            ))

        # One space separator
        fragments.append(('', ' ', focus))

        return fragments
