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