# 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

_jinja_env = Environment(
    loader=PackageLoader('pw_console'),
    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."""
    def setUp(self):
        self.maxDiff = None  # pylint: disable=invalid-name

    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_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_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()
