"""
Local configuration and fixture providing for the Plugin tests
"""

import subprocess
from os.path import dirname, join
from typing import Callable, Generator, Union

import pytest
from _pytest.config import Config


def get_csv(csv: str) -> str:
    """
    Helper Method: Read CSV file from the tests assets directory under ``tests/plugin/assets``.

    :param csv: Name of the CSV file, without the .csv extension
    :returns: CSV data as string
    """
    with open(join(dirname(__file__), "assets", f"{csv}.csv"), "rb") as csv_fh:
        csv_data = csv_fh.read()
    return csv_data.decode("utf-8")


@pytest.fixture(scope="session")
def simple_test_csv() -> str:
    """
    Test fixture: Good simple CSV

    :returns: CSV data as string
    """
    return get_csv("simple-test")


@pytest.fixture(scope="session")
def bad_test_csv() -> str:
    """
    Test fixture: Bad CSV

    :returns: Bad CSV data as string
    """
    return get_csv("bad-test")


@pytest.fixture(scope="session")
def text_test_csv() -> str:
    """
    Test Fixture: Text-only CSV

    :returns: Text-only CSV data as string
    """
    return get_csv("text-only")


@pytest.fixture(scope="session")
def simple_fruit_test() -> Union[Callable[[str], str], Callable[[str, str], str]]:
    """
    Test Fixture: Template of a simple test case

    :returns: A method where a data file can be filled in and what will return a valid pytest test case that can be
              saved to a .py file
    """
    with open(join(dirname(__file__), "assets", "fruit_test.tpl"), "rt", encoding="utf-8") as test_fh:
        test_data = test_fh.read()
    return lambda file, test="fruit": test_data.replace("{{data_file}}", file).replace("{{test_name}}", test)


@pytest.fixture(scope="session")
def simple_text_test() -> Callable[[str], str]:
    """
    Test Fixture: Template of a simple text test case

    :returns: A method where a data file can be filled in and what will return a valid pytest test case that can be
              saved to a .py file
    """
    with open(join(dirname(__file__), "assets", "text_test.tpl"), "rt", encoding="utf-8") as test_fh:
        test_data = test_fh.read()
    return lambda file: test_data.replace("{{data_file}}", file)


@pytest.fixture(scope="session", autouse=True)
def install_plugin_locally(pytestconfig: Config) -> Generator[None, None, None]:
    """
    Auto-use Test Fixture to install our plugin in the test environment, so that it can be used with the ``pytester``
    fixture. The package is removed after the test session automatically.

    :param pytestconfig: Fixture from pytest that contains the test configuration
    :returns: An empty generator (from the ``yield``), to let the tests run and cleanup afterwards
    """
    root = pytestconfig.rootpath
    _ = subprocess.run(["pip", "install", "-e", "."], shell=True, cwd=root, check=True, capture_output=True)
    yield
    _ = subprocess.run(
        ["pip", "uninstall", "-y", "pytest_csv_params"], shell=True, cwd=root, check=True, capture_output=True
    )
