import logging
import os

import mock
import pytest

from src.configuration import prepare_host, set_experiment_name, set_bootstrap_path, check_path_and_create
from src.helpers import PyTestRegex


class TestPrepareHost:

    @mock.patch("socket.gethostname", side_effect=["linux-aa9b", "ZAM144", "zam347", "jrtest", "jwtest",
                                                   "runner-6HmDp9Qd-project-2411-concurrent-01"])
    @mock.patch("getpass.getuser", return_value="testUser")
    @mock.patch("os.path.exists", return_value=True)
    def test_prepare_host(self, mock_host, mock_user, mock_path):
        assert prepare_host() == "/home/testUser/machinelearningtools/data/toar_daily/"
        assert prepare_host() == "/home/testUser/Data/toar_daily/"
        assert prepare_host() == "/home/testUser/Data/toar_daily/"
        assert prepare_host() == "/p/project/cjjsc42/testUser/DATA/toar_daily/"
        assert prepare_host() == "/p/project/deepacf/intelliaq/testUser/DATA/toar_daily/"
        assert prepare_host() == '/home/testUser/machinelearningtools/data/toar_daily/'

    @mock.patch("socket.gethostname", return_value="NotExistingHostName")
    @mock.patch("getpass.getuser", return_value="zombie21")
    def test_error_handling_unknown_host(self, mock_user, mock_host):
        with pytest.raises(OSError) as e:
            prepare_host()
        assert "unknown host 'NotExistingHostName'" in e.value.args[0]

    @mock.patch("getpass.getuser", return_value="zombie21")
    @mock.patch("src.configuration.path_config.check_path_and_create", side_effect=PermissionError)
    @mock.patch("os.path.exists", return_value=False)
    def test_error_handling(self, mock_path_exists, mock_cpath, mock_user):
        # if "runner-6HmDp9Qd-project-2411-concurrent" not in platform.node():
        # mock_host.return_value = "linux-aa9b"
        with pytest.raises(NotADirectoryError) as e:
            prepare_host()
        assert PyTestRegex(r"path '.*' does not exist for host '.*'\.") == e.value.args[0]
        with pytest.raises(NotADirectoryError) as e:
            prepare_host(False)
        # assert "does not exist for host 'linux-aa9b'" in e.value.args[0]
        assert PyTestRegex(r"path '.*' does not exist for host '.*'\.") == e.value.args[0]

    @mock.patch("socket.gethostname", side_effect=["linux-aa9b"])
    @mock.patch("getpass.getuser", return_value="testUser")
    @mock.patch("os.path.exists", return_value=False)
    @mock.patch("os.makedirs", side_effect=None)
    def test_os_path_exists(self, mock_host, mock_user, mock_path, mock_check):
        path = prepare_host()
        assert path == "/home/testUser/machinelearningtools/data/toar_daily/"


class TestSetExperimentName:

    def test_set_experiment(self):
        exp_name, exp_path = set_experiment_name()
        assert exp_name == "TestExperiment"
        assert exp_path == os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "TestExperiment"))
        exp_name, exp_path = set_experiment_name(experiment_name="2019-11-14", experiment_path=os.path.join(
            os.path.dirname(__file__), "test2"))
        assert exp_name == "2019-11-14_network"
        assert exp_path == os.path.abspath(os.path.join(os.path.dirname(__file__), "test2", exp_name))

    def test_set_experiment_from_sys(self):
        exp_name, _ = set_experiment_name(experiment_name="2019-11-14")
        assert exp_name == "2019-11-14_network"

    def test_set_experiment_hourly(self):
        exp_name, exp_path = set_experiment_name(sampling="hourly")
        assert exp_name == "TestExperiment_hourly"
        assert exp_path == os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "TestExperiment_hourly"))


class TestSetBootstrapPath:

    @mock.patch("os.makedirs", side_effect=None)
    def test_bootstrap_path_is_none(self, mock_makedir):
        bootstrap_path = set_bootstrap_path(None, 'TestDataPath/', 'daily')
        assert bootstrap_path == os.path.abspath('TestDataPath/../bootstrap_daily')

    @mock.patch("os.makedirs", side_effect=None)
    def test_bootstap_path_is_given(self, mock_makedir):
        bootstrap_path = set_bootstrap_path('Test/path/to/boots', None, None)
        assert bootstrap_path == os.path.abspath('./Test/path/to/boots')


class TestCheckPath:

    def test_check_path_and_create(self, caplog):
        caplog.set_level(logging.DEBUG)
        path = 'data/test'
        assert not os.path.exists('data/test')
        check_path_and_create(path)
        assert os.path.exists('data/test')
        assert caplog.messages[0] == "Created path: data/test"
        check_path_and_create(path)
        assert caplog.messages[1] == "Path already exists: data/test"
        os.rmdir('data/test')