import os
import sys
from pathlib import Path

import psutil
import pytest

from clarabot_nano_tests.core.utility.common import start_core_expect_error
from clarabot_nano_tests.core.utility.config import check_configs_empty, check_configs_default
from clarabot_nano_tests.testing.file import temp_dir, temp_path, temp_yaml
from clarabot_nano_tests.testing.process import pypopen


def _start_core_custom_config_expect_error(user_config_dir, args, error, env=None, return_code=1, timeout=3):
    check_configs_empty(user_config_dir)
    start_core_expect_error(args, error, env=env, return_code=return_code, timeout=timeout)
    check_configs_empty(user_config_dir)


def test_core_start_custom_config_error_bootstrap(tmpdir, reset_user_app_config_dir):
    root = temp_dir(tmpdir)
    _start_core_custom_config_expect_error(
        reset_user_app_config_dir,
        ["-c", str(root), "--headless"],
        "Exception: Both bootstrap_config_dir and bootstrap_data_dir must be specified for a new instance",
    )


def test_core_start_custom_config_error_invalid_path(tmpdir, reset_user_app_config_dir):
    root = temp_path(tmpdir)
    _start_core_custom_config_expect_error(
        reset_user_app_config_dir,
        ["-c", str(root), "--headless", "--bootstrap_config_dir", "asdf", "--bootstrap_data_dir", "xyz"],
        "ValidationError: Path is not absolute",
    )


@pytest.mark.skipif(sys.platform.startswith("win"), reason="fixme on windows")
def test_core_start_custom_config_error_inaccessible(tmpdir, reset_user_app_config_dir):
    root = temp_yaml(tmpdir, {"test": "me"})
    os.chmod(str(root), 0o000)  # TODO: fix on windows
    _start_core_custom_config_expect_error(
        reset_user_app_config_dir,
        ["-c", str(root), "--headless"],
        "Exception: Provided path to local configuration must be a readable file",
    )


def test_core_start_custom_config_bootstrap(
    tmpdir, reset_user_app_config_dir, reset_user_app_data_dir, dev_nano_root_dir
):
    local_config = Path(temp_path(tmpdir))
    config_dir = Path(temp_path(tmpdir))
    data_dir = Path(temp_path(tmpdir))
    check_configs_empty(reset_user_app_config_dir)
    with pypopen(
        [
            "clarabot_nano",
            "-c",
            str(local_config),
            "--headless",
            "--bootstrap_config_dir",
            str(config_dir),
            "--bootstrap_data_dir",
            str(data_dir),
        ],
        env={"CBNANO_ROOT": str(dev_nano_root_dir)},
    ) as p:
        with pytest.raises(psutil.TimeoutExpired):
            p.wait(5)
    assert p.returncode == 0
    check_configs_empty(reset_user_app_config_dir)
    check_configs_default(config_dir, data_dir, local_config)
