# 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 logging
import unittest
from unittest.mock import MagicMock

from prompt_toolkit.application import create_app_session
from prompt_toolkit.output import ColorDepth

# inclusive-language: ignore
from prompt_toolkit.output import DummyOutput as FakeOutput

from pw_console.console_app import ConsoleApp
from pw_console.console_prefs import ConsolePrefs
from pw_console.window_manager import _WINDOW_SPLIT_ADJUST
from pw_console.window_list import _WINDOW_HEIGHT_ADJUST, DisplayMode


def _create_console_app(logger_count=2):
    prefs = ConsolePrefs(
        project_file=False, project_user_file=False, user_file=False
    )
    prefs.set_code_theme('default')
    console_app = ConsoleApp(color_depth=ColorDepth.DEPTH_8_BIT, prefs=prefs)
    console_app.focus_on_container = MagicMock()

    loggers = {}
    for i in range(logger_count):
        loggers['Log{}'.format(i)] = [logging.getLogger('test_log{}'.format(i))]
    for window_title, logger_instances in loggers.items():
        console_app.add_log_handler(window_title, logger_instances)
    return console_app


_WINDOW_MANAGER_WIDTH = 80
_WINDOW_MANAGER_HEIGHT = 30
_DEFAULT_WINDOW_WIDTH = 10
_DEFAULT_WINDOW_HEIGHT = 10


def _window_list_widths(window_manager):
    window_manager.update_window_manager_size(
        _WINDOW_MANAGER_WIDTH, _WINDOW_MANAGER_HEIGHT
    )

    return [
        window_list.width.preferred
        for window_list in window_manager.window_lists
    ]


def _window_list_heights(window_manager):
    window_manager.update_window_manager_size(
        _WINDOW_MANAGER_WIDTH, _WINDOW_MANAGER_HEIGHT
    )

    return [
        window_list.height.preferred
        for window_list in window_manager.window_lists
    ]


def _window_pane_widths(window_manager, window_list_index=0):
    window_manager.update_window_manager_size(
        _WINDOW_MANAGER_WIDTH, _WINDOW_MANAGER_HEIGHT
    )

    return [
        pane.width.preferred
        for pane in window_manager.window_lists[window_list_index].active_panes
    ]


def _window_pane_heights(window_manager, window_list_index=0):
    window_manager.update_window_manager_size(
        _WINDOW_MANAGER_WIDTH, _WINDOW_MANAGER_HEIGHT
    )

    return [
        pane.height.preferred
        for pane in window_manager.window_lists[window_list_index].active_panes
    ]


def _window_pane_counts(window_manager):
    return [
        len(window_list.active_panes)
        for window_list in window_manager.window_lists
    ]


def window_pane_titles(window_manager):
    return [
        [
            pane.pane_title() + ' - ' + pane.pane_subtitle()
            for pane in window_list.active_panes
        ]
        for window_list in window_manager.window_lists
    ]


def target_list_and_pane(window_manager, list_index, pane_index):
    # pylint: disable=protected-access
    # Bypass prompt_toolkit has_focus()
    pane = window_manager.window_lists[list_index].active_panes[pane_index]
    # If the pane is in focus it will be visible.
    pane.show_pane = True
    window_manager._get_active_window_list_and_pane = MagicMock(  # type: ignore
        return_value=(
            window_manager.window_lists[list_index],
            window_manager.window_lists[list_index].active_panes[pane_index],
        )
    )


class TestWindowManager(unittest.TestCase):
    # pylint: disable=protected-access
    """Tests for window management functions."""

    def setUp(self):
        self.maxDiff = None  # pylint: disable=invalid-name

    def test_find_window_list_and_pane(self) -> None:
        """Test getting the window list for a given pane."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=3)

            window_manager = console_app.window_manager
            self.assertEqual([4], _window_pane_counts(window_manager))

            # Move 2 windows to the right into their own splits
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 1, 0)
            window_manager.move_pane_right()
            # 3 splits, first split has 2 windows
            self.assertEqual([2, 1, 1], _window_pane_counts(window_manager))

            # Move the first window in the first split left
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_left()
            # 4 splits, each with their own window
            self.assertEqual([1, 1, 1, 1], _window_pane_counts(window_manager))

            # Move the first window to the right
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            # 3 splits, first split has 2 windows
            self.assertEqual([2, 1, 1], _window_pane_counts(window_manager))

            target_pane = window_manager.window_lists[2].active_panes[0]

            (
                result_window_list,
                result_pane_index,
            ) = window_manager.find_window_list_and_pane_index(target_pane)
            self.assertEqual(
                (result_window_list, result_pane_index),
                (window_manager.window_lists[2], 0),
            )
            window_manager.remove_pane(target_pane)
            self.assertEqual([2, 1], _window_pane_counts(window_manager))

    def test_window_list_moving_and_resizing(self) -> None:
        """Test window split movement resizing."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=3)

            window_manager = console_app.window_manager

            target_list_and_pane(window_manager, 0, 0)
            # Should have one window list split of size 50.
            self.assertEqual(
                _window_list_widths(window_manager),
                [_WINDOW_MANAGER_WIDTH],
            )

            # Move one pane to the right, creating a new window_list split.
            window_manager.move_pane_right()

            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 2),
                    int(_WINDOW_MANAGER_WIDTH / 2),
                ],
            )

            # Move another pane to the right twice, creating a third
            # window_list split.
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()

            # Above window pane is at a new location
            target_list_and_pane(window_manager, 1, 0)
            window_manager.move_pane_right()

            # Should have 3 splits now
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 3),
                    int(_WINDOW_MANAGER_WIDTH / 3),
                    int(_WINDOW_MANAGER_WIDTH / 3),
                ],
            )

            # Total of 4 active panes
            self.assertEqual(len(list(window_manager.active_panes())), 4)

            # Target the middle split
            target_list_and_pane(window_manager, 1, 0)
            # Shrink the middle split twice
            window_manager.shrink_split()
            window_manager.shrink_split()
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 3),
                    int(_WINDOW_MANAGER_WIDTH / 3) - (2 * _WINDOW_SPLIT_ADJUST),
                    int(_WINDOW_MANAGER_WIDTH / 3) + (2 * _WINDOW_SPLIT_ADJUST),
                ],
            )

            # Target the first split
            target_list_and_pane(window_manager, 0, 0)
            window_manager.reset_split_sizes()
            # Shrink the first split twice
            window_manager.shrink_split()
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 3) - (1 * _WINDOW_SPLIT_ADJUST),
                    int(_WINDOW_MANAGER_WIDTH / 3) + (1 * _WINDOW_SPLIT_ADJUST),
                    int(_WINDOW_MANAGER_WIDTH / 3),
                ],
            )

            # Target the third (last) split
            target_list_and_pane(window_manager, 2, 0)
            window_manager.reset_split_sizes()
            # Shrink the third split once
            window_manager.shrink_split()
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 3),
                    int(_WINDOW_MANAGER_WIDTH / 3) + (1 * _WINDOW_SPLIT_ADJUST),
                    int(_WINDOW_MANAGER_WIDTH / 3) - (1 * _WINDOW_SPLIT_ADJUST),
                ],
            )

            window_manager.reset_split_sizes()
            # Enlarge the third split a few times.
            window_manager.enlarge_split()
            window_manager.enlarge_split()
            window_manager.enlarge_split()
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 3),
                    int(_WINDOW_MANAGER_WIDTH / 3) - (3 * _WINDOW_SPLIT_ADJUST),
                    int(_WINDOW_MANAGER_WIDTH / 3) + (3 * _WINDOW_SPLIT_ADJUST),
                ],
            )

            # Target the middle split
            target_list_and_pane(window_manager, 1, 0)
            # Move the middle window pane left
            window_manager.move_pane_left()
            # This is called on the next render pass
            window_manager.rebalance_window_list_sizes()
            # Middle split should be removed
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 2) - (3 * _WINDOW_SPLIT_ADJUST),
                    # This split is removed
                    int(_WINDOW_MANAGER_WIDTH / 2) + (2 * _WINDOW_SPLIT_ADJUST),
                ],
            )

            # Revert sizes to default
            window_manager.reset_split_sizes()
            self.assertEqual(
                _window_list_widths(window_manager),
                [
                    int(_WINDOW_MANAGER_WIDTH / 2),
                    int(_WINDOW_MANAGER_WIDTH / 2),
                ],
            )

    def test_get_pane_titles(self) -> None:
        """Test window resizing."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=3)

            window_manager = console_app.window_manager
            list_pane_titles = [
                # Remove mouse click handler partials in tup[2]
                [(tup[0], tup[1]) for tup in window_list.get_pane_titles()]
                for window_list in window_manager.window_lists
            ]
            self.assertEqual(
                list_pane_titles[0],
                [
                    ('', ' '),
                    ('class:window-tab-inactive', ' Log2 test_log2 '),
                    ('', ' '),
                    ('class:window-tab-inactive', ' Log1 test_log1 '),
                    ('', ' '),
                    ('class:window-tab-inactive', ' Log0 test_log0 '),
                    ('', ' '),
                    ('class:window-tab-inactive', ' Python Repl  '),
                    ('', ' '),
                ],
            )

    def test_window_pane_movement_resizing(self) -> None:
        """Test window resizing."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=3)

            window_manager = console_app.window_manager

            # 4 panes, 3 for the loggers and 1 for the repl.
            self.assertEqual(
                len(window_manager.first_window_list().active_panes), 4
            )

            def target_window_pane(index: int):
                # Bypass prompt_toolkit has_focus()
                window_manager._get_active_window_list_and_pane = (
                    MagicMock(  # type: ignore
                        return_value=(
                            window_manager.window_lists[0],
                            window_manager.window_lists[0].active_panes[index],
                        )
                    )
                )
                window_list = console_app.window_manager.first_window_list()
                window_list.get_current_active_pane = MagicMock(  # type: ignore
                    return_value=window_list.active_panes[index]
                )

            # Target the first window pane
            target_window_pane(0)

            # Shrink the first pane
            window_manager.shrink_pane()
            self.assertEqual(
                _window_pane_heights(window_manager),
                [
                    _DEFAULT_WINDOW_HEIGHT - (1 * _WINDOW_HEIGHT_ADJUST),
                    _DEFAULT_WINDOW_HEIGHT + (1 * _WINDOW_HEIGHT_ADJUST),
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT,
                ],
            )

            # Reset pane sizes
            window_manager.window_lists[0].current_window_list_height = (
                4 * _DEFAULT_WINDOW_HEIGHT
            )
            window_manager.reset_pane_sizes()
            self.assertEqual(
                _window_pane_heights(window_manager),
                [
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT,
                ],
            )

            # Shrink last pane
            target_window_pane(3)

            window_manager.shrink_pane()
            self.assertEqual(
                _window_pane_heights(window_manager),
                [
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT + (1 * _WINDOW_HEIGHT_ADJUST),
                    _DEFAULT_WINDOW_HEIGHT - (1 * _WINDOW_HEIGHT_ADJUST),
                ],
            )

            # Enlarge second pane
            target_window_pane(1)
            window_manager.reset_pane_sizes()

            window_manager.enlarge_pane()
            window_manager.enlarge_pane()
            self.assertEqual(
                _window_pane_heights(window_manager),
                [
                    _DEFAULT_WINDOW_HEIGHT,
                    _DEFAULT_WINDOW_HEIGHT + (2 * _WINDOW_HEIGHT_ADJUST),
                    _DEFAULT_WINDOW_HEIGHT - (2 * _WINDOW_HEIGHT_ADJUST),
                    _DEFAULT_WINDOW_HEIGHT,
                ],
            )

            # Check window pane ordering
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log2 - test_log2',
                        'Log1 - test_log1',
                        'Log0 - test_log0',
                        'Python Repl - ',
                    ],
                ],
            )

            target_window_pane(0)
            window_manager.move_pane_down()
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log1 - test_log1',
                        'Log2 - test_log2',
                        'Log0 - test_log0',
                        'Python Repl - ',
                    ],
                ],
            )
            target_window_pane(2)
            window_manager.move_pane_up()
            target_window_pane(1)
            window_manager.move_pane_up()
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log0 - test_log0',
                        'Log1 - test_log1',
                        'Log2 - test_log2',
                        'Python Repl - ',
                    ],
                ],
            )
            target_window_pane(0)
            window_manager.move_pane_up()
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log0 - test_log0',
                        'Log1 - test_log1',
                        'Log2 - test_log2',
                        'Python Repl - ',
                    ],
                ],
            )

    def test_focus_next_and_previous_pane(self) -> None:
        """Test switching focus to next and previous window panes."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=4)

            window_manager = console_app.window_manager
            window_manager.window_lists[0].set_display_mode(DisplayMode.STACK)
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log3 - test_log3',
                        'Log2 - test_log2',
                        'Log1 - test_log1',
                        'Log0 - test_log0',
                        'Python Repl - ',
                    ],
                ],
            )

            # Scenario: Move between panes with a single stacked window list.

            # Set the first pane in focus.
            target_list_and_pane(window_manager, 0, 0)
            # Switch focus to the next pane
            window_manager.focus_next_pane()
            # Pane index 1 should now be focused.
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[1]
            )
            console_app.focus_on_container.reset_mock()

            # Set the first pane in focus.
            target_list_and_pane(window_manager, 0, 0)
            # Switch focus to the previous pane
            window_manager.focus_previous_pane()
            # Previous pane should wrap around to the last pane in the first
            # window_list.
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[-1]
            )
            console_app.focus_on_container.reset_mock()

            # Set the last pane in focus.
            target_list_and_pane(window_manager, 0, 4)
            # Switch focus to the next pane
            window_manager.focus_next_pane()
            # Next pane should wrap around to the first pane in the first
            # window_list.
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[0]
            )
            console_app.focus_on_container.reset_mock()

            # Scenario: Move between panes with a single tabbed window list.

            # Switch to Tabbed view mode
            window_manager.window_lists[0].set_display_mode(DisplayMode.TABBED)
            # The set_display_mode call above will call focus_on_container once.
            console_app.focus_on_container.reset_mock()

            # Setup the switch_to_tab mock
            window_manager.window_lists[0].switch_to_tab = MagicMock(
                wraps=window_manager.window_lists[0].switch_to_tab
            )

            # Set the first pane/tab in focus.
            target_list_and_pane(window_manager, 0, 0)
            # Switch focus to the next pane/tab
            window_manager.focus_next_pane()
            # Check switch_to_tab is called
            window_manager.window_lists[
                0
            ].switch_to_tab.assert_called_once_with(1)
            # And that focus_on_container is called only once
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[1]
            )
            console_app.focus_on_container.reset_mock()
            window_manager.window_lists[0].switch_to_tab.reset_mock()

            # Set the last pane/tab in focus.
            target_list_and_pane(window_manager, 0, 4)
            # Switch focus to the next pane/tab
            window_manager.focus_next_pane()
            # Check switch_to_tab is called
            window_manager.window_lists[
                0
            ].switch_to_tab.assert_called_once_with(0)
            # And that focus_on_container is called only once
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[0]
            )
            console_app.focus_on_container.reset_mock()
            window_manager.window_lists[0].switch_to_tab.reset_mock()

            # Set the first pane/tab in focus.
            target_list_and_pane(window_manager, 0, 0)
            # Switch focus to the prev pane/tab
            window_manager.focus_previous_pane()
            # Check switch_to_tab is called
            window_manager.window_lists[
                0
            ].switch_to_tab.assert_called_once_with(4)
            # And that focus_on_container is called only once
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[4]
            )
            console_app.focus_on_container.reset_mock()
            window_manager.window_lists[0].switch_to_tab.reset_mock()

            # Scenario: Move between multiple window lists with mixed stacked
            # and tabbed view modes.

            # Setup: Move two panes to the right into their own stacked
            # window_list.
            target_list_and_pane(window_manager, 0, 4)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 0, 3)
            window_manager.move_pane_right()
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log3 - test_log3',
                        'Log2 - test_log2',
                        'Log1 - test_log1',
                    ],
                    [
                        'Log0 - test_log0',
                        'Python Repl - ',
                    ],
                ],
            )

            # Setup the switch_to_tab mock on the second window_list
            window_manager.window_lists[1].switch_to_tab = MagicMock(
                wraps=window_manager.window_lists[1].switch_to_tab
            )

            # Set Log1 in focus
            target_list_and_pane(window_manager, 0, 2)
            window_manager.focus_next_pane()
            # Log0 should now have focus
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[1].active_panes[0]
            )
            console_app.focus_on_container.reset_mock()

            # Set Log0 in focus
            target_list_and_pane(window_manager, 1, 0)
            window_manager.focus_previous_pane()
            # Log1 should now have focus
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[2]
            )
            # The first window list is in tabbed mode so switch_to_tab should be
            # called once.
            window_manager.window_lists[
                0
            ].switch_to_tab.assert_called_once_with(2)
            # Reset
            window_manager.window_lists[0].switch_to_tab.reset_mock()
            console_app.focus_on_container.reset_mock()

            # Set Python Repl in focus
            target_list_and_pane(window_manager, 1, 1)
            window_manager.focus_next_pane()
            # Log3 should now have focus
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[0]
            )
            window_manager.window_lists[
                0
            ].switch_to_tab.assert_called_once_with(0)
            # Reset
            window_manager.window_lists[0].switch_to_tab.reset_mock()
            console_app.focus_on_container.reset_mock()

            # Set Log3 in focus
            target_list_and_pane(window_manager, 0, 0)
            window_manager.focus_next_pane()
            # Log2 should now have focus
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[0].active_panes[1]
            )
            window_manager.window_lists[
                0
            ].switch_to_tab.assert_called_once_with(1)
            # Reset
            window_manager.window_lists[0].switch_to_tab.reset_mock()
            console_app.focus_on_container.reset_mock()

            # Set Python Repl in focus
            target_list_and_pane(window_manager, 1, 1)
            window_manager.focus_previous_pane()
            # Log0 should now have focus
            console_app.focus_on_container.assert_called_once_with(
                window_manager.window_lists[1].active_panes[0]
            )
            # The second window list is in stacked mode so switch_to_tab should
            # not be called.
            window_manager.window_lists[1].switch_to_tab.assert_not_called()
            # Reset
            window_manager.window_lists[1].switch_to_tab.reset_mock()
            console_app.focus_on_container.reset_mock()

    def test_resize_vertical_splits(self) -> None:
        """Test resizing window splits."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=4)
            window_manager = console_app.window_manager

            # Required before moving windows
            window_manager.update_window_manager_size(
                _WINDOW_MANAGER_WIDTH, _WINDOW_MANAGER_HEIGHT
            )
            window_manager.create_root_container()

            # Vertical split by default
            self.assertTrue(window_manager.vertical_window_list_spliting())

            # Move windows to create 3 splits
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 1, 1)
            window_manager.move_pane_right()

            # Check windows are where expected
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log1 - test_log1',
                        'Log0 - test_log0',
                        'Python Repl - ',
                    ],
                    [
                        'Log2 - test_log2',
                    ],
                    [
                        'Log3 - test_log3',
                    ],
                ],
            )

            # Check initial split widths
            widths = [
                int(_WINDOW_MANAGER_WIDTH / 3),
                int(_WINDOW_MANAGER_WIDTH / 3),
                int(_WINDOW_MANAGER_WIDTH / 3),
            ]
            self.assertEqual(_window_list_widths(window_manager), widths)

            # Decrease size of first split
            window_manager.adjust_split_size(window_manager.window_lists[0], -4)
            widths = [
                widths[0] - (4 * _WINDOW_SPLIT_ADJUST),
                widths[1] + (4 * _WINDOW_SPLIT_ADJUST),
                widths[2],
            ]
            self.assertEqual(_window_list_widths(window_manager), widths)

            # Increase size of last split
            widths = [
                widths[0],
                widths[1] - (4 * _WINDOW_SPLIT_ADJUST),
                widths[2] + (4 * _WINDOW_SPLIT_ADJUST),
            ]
            window_manager.adjust_split_size(window_manager.window_lists[2], 4)
            self.assertEqual(_window_list_widths(window_manager), widths)

            # Check heights are all the same
            window_manager.rebalance_window_list_sizes()
            heights = [
                int(_WINDOW_MANAGER_HEIGHT),
                int(_WINDOW_MANAGER_HEIGHT),
                int(_WINDOW_MANAGER_HEIGHT),
            ]
            self.assertEqual(_window_list_heights(window_manager), heights)

    def test_resize_horizontal_splits(self) -> None:
        """Test resizing window splits."""
        with create_app_session(output=FakeOutput()):
            console_app = _create_console_app(logger_count=4)
            window_manager = console_app.window_manager

            # We want horizontal window splits
            window_manager.vertical_window_list_spliting = MagicMock(
                return_value=False
            )
            self.assertFalse(window_manager.vertical_window_list_spliting())

            # Required before moving windows
            window_manager.update_window_manager_size(
                _WINDOW_MANAGER_WIDTH, _WINDOW_MANAGER_HEIGHT
            )
            window_manager.create_root_container()

            # Move windows to create 3 splits
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 0, 0)
            window_manager.move_pane_right()
            target_list_and_pane(window_manager, 1, 1)
            window_manager.move_pane_right()

            # Check windows are where expected
            self.assertEqual(
                window_pane_titles(window_manager),
                [
                    [
                        'Log1 - test_log1',
                        'Log0 - test_log0',
                        'Python Repl - ',
                    ],
                    [
                        'Log2 - test_log2',
                    ],
                    [
                        'Log3 - test_log3',
                    ],
                ],
            )

            # Check initial split widths
            heights = [
                int(_WINDOW_MANAGER_HEIGHT / 3),
                int(_WINDOW_MANAGER_HEIGHT / 3),
                int(_WINDOW_MANAGER_HEIGHT / 3),
            ]
            self.assertEqual(_window_list_heights(window_manager), heights)

            # Decrease size of first split
            window_manager.adjust_split_size(window_manager.window_lists[0], -4)
            heights = [
                heights[0] - (4 * _WINDOW_SPLIT_ADJUST),
                heights[1] + (4 * _WINDOW_SPLIT_ADJUST),
                heights[2],
            ]
            self.assertEqual(_window_list_heights(window_manager), heights)

            # Increase size of last split
            heights = [
                heights[0],
                heights[1] - (4 * _WINDOW_SPLIT_ADJUST),
                heights[2] + (4 * _WINDOW_SPLIT_ADJUST),
            ]
            window_manager.adjust_split_size(window_manager.window_lists[2], 4)
            self.assertEqual(_window_list_heights(window_manager), heights)

            # Check widths are all the same
            window_manager.rebalance_window_list_sizes()
            widths = [
                int(_WINDOW_MANAGER_WIDTH),
                int(_WINDOW_MANAGER_WIDTH),
                int(_WINDOW_MANAGER_WIDTH),
            ]
            self.assertEqual(_window_list_widths(window_manager), widths)


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