# 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.
"""Tests for pw_console.console_app"""

import inspect
import logging
import unittest
from unittest.mock import MagicMock

from jinja2 import Environment, PackageLoader, make_logging_undefined
from prompt_toolkit.key_binding import KeyBindings

from pw_console.help_window import HelpWindow

_PW_CONSOLE_MODULE = 'pw_console'


_jinja_env = Environment(
    loader=PackageLoader(_PW_CONSOLE_MODULE),
    undefined=make_logging_undefined(logger=logging.getLogger('pw_console')),
    trim_blocks=True,
    lstrip_blocks=True,
)


def _create_app_mock():
    template = _jinja_env.get_template('keybind_list.jinja')
    mock_app = MagicMock()
    mock_app.get_template = MagicMock(return_value=template)
    return mock_app


class TestHelpWindow(unittest.TestCase):
    """Tests for HelpWindow text and keybind lists."""

    maxDiff = None

    def test_instantiate(self) -> None:
        app = _create_app_mock()
        help_window = HelpWindow(app)
        self.assertIsNotNone(help_window)

    # pylint: disable=unused-variable,unused-argument
    def test_add_keybind_help_text(self) -> None:
        key_bindings = KeyBindings()

        @key_bindings.add('f1')
        def show_help(event):
            """Toggle help window."""

        @key_bindings.add('c-w')
        @key_bindings.add('c-q')
        def exit_(event):
            """Quit the application."""

        app = _create_app_mock()

        help_window = HelpWindow(app)
        help_window.add_keybind_help_text('Global', key_bindings)

        self.assertEqual(
            help_window.help_text_sections,
            {
                'Global': {
                    'Quit the application.': ['Ctrl-Q', 'Ctrl-W'],
                    'Toggle help window.': ['F1'],
                }
            },
        )

    def test_generate_keybind_help_text(self) -> None:
        """Test keybind list template generation."""
        global_bindings = KeyBindings()

        @global_bindings.add('f1')
        def show_help(event):
            """Toggle help window."""

        @global_bindings.add('c-w')
        @global_bindings.add('c-q')
        def exit_(event):
            """Quit the application."""

        focus_bindings = KeyBindings()

        @focus_bindings.add('s-tab')
        @focus_bindings.add('c-right')
        @focus_bindings.add('c-down')
        def app_focus_next(event):
            """Move focus to the next widget."""

        @focus_bindings.add('c-left')
        @focus_bindings.add('c-up')
        def app_focus_previous(event):
            """Move focus to the previous widget."""

        app = _create_app_mock()

        help_window = HelpWindow(
            app,
            preamble='Pigweed CLI v0.1',
            additional_help_text=inspect.cleandoc(
                """
                Welcome to the Pigweed Console!
                Please enjoy this extra help text.
            """
            ),
        )
        help_window.add_keybind_help_text('Global', global_bindings)
        help_window.add_keybind_help_text('Focus', focus_bindings)
        help_window.generate_keybind_help_text()

        self.assertIn(
            inspect.cleandoc(
                """
            Welcome to the Pigweed Console!
            Please enjoy this extra help text.
            """
            ),
            help_window.help_text,
        )
        self.assertIn(
            inspect.cleandoc(
                """
            ==== Global Keys ====
            """
            ),
            help_window.help_text,
        )
        self.assertIn(
            inspect.cleandoc(
                """
            Toggle help window. -----------------  F1
            Quit the application. ---------------  Ctrl-Q
                                                   Ctrl-W
            """
            ),
            help_window.help_text,
        )
        self.assertIn(
            inspect.cleandoc(
                """
            ==== Focus Keys ====
            """
            ),
            help_window.help_text,
        )
        self.assertIn(
            inspect.cleandoc(
                """
            Move focus to the next widget. ------  Ctrl-Down
                                                   Ctrl-Right
                                                   Shift-Tab
            Move focus to the previous widget. --  Ctrl-Left
                                                   Ctrl-Up
            """
            ),
            help_window.help_text,
        )


if __name__ == '__main__':
    unittest.main()
