from pathlib import Path
from unittest.mock import patch

import pytest

from dopt_sensor_anomalies import _find_paths


@pytest.fixture()
def temp_model_folder_empty(tmp_path_factory) -> Path:
    return tmp_path_factory.mktemp("empty")


@pytest.fixture()
def temp_model_folder_full(tmp_path_factory) -> Path:
    folder = tmp_path_factory.mktemp("full")
    left_hand_model = folder / "this_file_contains_the_left_hand_side_model.pth"
    right_hand_model = folder / "this_file_contains_the_right_hand_side_model.pth"
    left_hand_model.touch()
    right_hand_model.touch()
    return folder


@pytest.fixture()
def temp_model_folder_only_left(tmp_path_factory) -> Path:
    folder = tmp_path_factory.mktemp("only_left")
    left_hand_model = folder / "this_file_contains_the_left_hand_side_model.pth"
    left_hand_model.touch()
    return folder


@pytest.fixture()
def temp_model_folder_only_right(tmp_path_factory) -> Path:
    folder = tmp_path_factory.mktemp("only_right")
    right_hand_model = folder / "this_file_contains_the_right_hand_side_model.pth"
    right_hand_model.touch()
    return folder


@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "not-found")
def test_get_model_folder_Fail_NotFoundApplicationRoot():
    with pytest.raises(
        FileNotFoundError, match="application's root directory could not be determined"
    ):
        _ = _find_paths.get_model_folder()


@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "lib")
@patch("dopt_sensor_anomalies._find_paths.MODEL_FOLDER_NAME", "not-found")
def test_get_model_folder_Fail_NotFoundModelFolder():
    with pytest.raises(
        FileNotFoundError,
        match="model folder was not found in the application's root directory",
    ):
        _ = _find_paths.get_model_folder()


@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "lib")
def test_get_model_folder_Success():
    ret = _find_paths.get_model_folder()
    assert ret is not None
    assert ret.name == _find_paths.MODEL_FOLDER_NAME


def test_get_detection_models_FailEmptyDir(temp_model_folder_empty):
    with pytest.raises(ValueError):
        _ = _find_paths.get_detection_models(temp_model_folder_empty)


def test_get_detection_models_FailOnlyLeft(temp_model_folder_only_left):
    with pytest.raises(ValueError):
        _ = _find_paths.get_detection_models(temp_model_folder_only_left)


def test_get_detection_models_FailOnlyRight(temp_model_folder_only_right):
    with pytest.raises(ValueError):
        _ = _find_paths.get_detection_models(temp_model_folder_only_right)


def test_get_detection_models_FailTooManyLeft(temp_model_folder_full):
    right_hand_model = (
        temp_model_folder_full / "this_file_contains_the_left_hand_side_model2.pth"
    )
    right_hand_model.touch()

    with pytest.raises(ValueError):
        _ = _find_paths.get_detection_models(temp_model_folder_full)


def test_get_detection_models_FailTooManyRight(temp_model_folder_full):
    right_hand_model = (
        temp_model_folder_full / "this_file_contains_the_right_hand_side_model2.pth"
    )
    right_hand_model.touch()

    with pytest.raises(ValueError):
        _ = _find_paths.get_detection_models(temp_model_folder_full)


def test_get_detection_models_Success(temp_model_folder_full):
    models = _find_paths.get_detection_models(temp_model_folder_full)
    assert "left_hand" in models["left"].name
    assert "right_hand" in models["right"].name
