# 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:
        bindings = KeyBindings()

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

        @bindings.add('c-w')
        @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', 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("""
            Pigweed CLI v0.1

            ================================ Help ===============================

            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. ------  BackTab, Ctrl-Down, Ctrl-Right
            Move focus to the previous widget. --  Ctrl-Left, Ctrl-Up
            """),
            help_window.help_text,
        )


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