# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright © Spyder Project Contributors
#
# Licensed under the terms of the MIT License
# (see spyder/__init__.py for details)
# -----------------------------------------------------------------------------

"""
Tests for the Projects plugin.
"""

# Standard library imports
try:
    from unittest.mock import Mock
except ImportError:
    from mock import Mock  # Python 2

# Third party imports
import pytest

# Local imports
import spyder.plugins
from spyder.plugins.projects import Projects
from spyder.py3compat import to_text_string


# =============================================================================
# Fixtures
# =============================================================================
@pytest.fixture
def projects(qtbot, mocker):
    """Projects plugin fixture."""

    class MainWindowMock(object):
        def __getattr__(self, attr):
            if attr == 'ipyconsole' or attr == 'editor':
                return None
            else:
                return Mock()

    # Create plugin
    projects = Projects(parent=None)

    # Patching necessary to test visible_if_project_open
    projects.shortcut = None
    mocker.patch.object(spyder.plugins.SpyderDockWidget,
                        'install_tab_event_filter')
    mocker.patch.object(projects, 'toggle_view_action')
    projects.create_dockwidget()

    # This can only be done at this point
    projects.main = MainWindowMock()

    qtbot.addWidget(projects)
    projects.show()
    return projects


# =============================================================================
# Tests
# =============================================================================
@pytest.mark.parametrize("test_directory", [u'測試', u'اختبار', u"test_dir"])
def test_open_project(projects, tmpdir, test_directory):
    """Test that we can create a project in a given directory."""
    # Create the directory
    path = to_text_string(tmpdir.mkdir(test_directory))

    # Open project in path
    projects.open_project(path=path)

    # Verify that we created a valid project
    assert projects.is_valid_project(path)

    # Close project
    projects.close_project()


@pytest.mark.parametrize('value', [True, False])
def test_close_project_sets_visible_config(projects, tmpdir, value):
    """Test that when project is closed, the config option
    visible_if_project_open is set to the correct value."""
    # Set config to opposite value so that we can check that it's set correctly
    projects.set_option('visible_if_project_open', not value)

    projects.open_project(path=to_text_string(tmpdir))
    if value:
        projects.show_explorer()
    else:
        projects.dockwidget.close()
    projects.close_project()
    assert projects.get_option('visible_if_project_open') == value


@pytest.mark.parametrize('value', [True, False])
def test_closing_plugin_sets_visible_config(projects, tmpdir, value):
    """Test that closing_plugin() sets config option visible_if_project_open
    if a project is open."""
    projects.set_option('visible_if_project_open', not value)
    projects.closing_plugin()

    # No project is open so config option should remain unchanged
    assert projects.get_option('visible_if_project_open') == (not value)

    projects.open_project(path=to_text_string(tmpdir))
    if value:
        projects.show_explorer()
    else:
        projects.dockwidget.close()
    projects.close_project()
    assert projects.get_option('visible_if_project_open') == value


@pytest.mark.parametrize('value', [True, False])
def test_open_project_uses_visible_config(projects, tmpdir, value):
    """Test that when a project is opened, the project explorer is only opened
    if the config option visible_if_project_open is set."""
    projects.set_option('visible_if_project_open', value)
    projects.open_project(path=to_text_string(tmpdir))
    assert projects.dockwidget.isVisible() == value


def test_recent_projects_menu_action(projects, tmpdir):
    """
    Test that the actions of the submenu 'Recent Projects' in the 'Projects'
    main menu are working as expected.
    Regression test for Issue #8450.
    """
    recent_projects_len = len(projects.recent_projects)

    # Create the directories.
    path0 = to_text_string(tmpdir.mkdir('project0'))
    path1 = to_text_string(tmpdir.mkdir('project1'))
    path2 = to_text_string(tmpdir.mkdir('project2'))

    # Open projects in path0, path1, and path2.
    projects.open_project(path=path0)
    projects.open_project(path=path1)
    projects.open_project(path=path2)
    assert (len(projects.recent_projects_actions) ==
            recent_projects_len + 3 + 2)
    assert projects.get_active_project().root_path == path2

    # Trigger project1 in the list of Recent Projects actions.
    projects.recent_projects_actions[1].trigger()
    assert projects.get_active_project().root_path == path1

    # Trigger project0 in the list of Recent Projects actions.
    projects.recent_projects_actions[2].trigger()
    assert projects.get_active_project().root_path == path0


if __name__ == "__main__":
    pytest.main()
