"""
Test the reading of CSV files
=============================

**Module:** ``tests.test_read_csv``
"""

from os.path import dirname, join
from typing import Optional, Type

import pytest

from _ptcsvp.parametrize import read_csv
from pytest_csv_params.dialect import CsvParamsDefaultDialect
from pytest_csv_params.exception import CsvParamsDataFileInvalid, CsvParamsDataFileNotFound


@pytest.mark.parametrize(
    ["csv_file", "base_dir", "expect_lines", "expect_exception", "expect_message"],
    [
        ("test1.csv", join(dirname(__file__), "assets"), 6, None, None),
        (join(dirname(__file__), "assets", "test1.csv"), None, 6, None, None),
        ("test2.csv", join(dirname(__file__), "assets"), 6, None, None),
        (join(dirname(__file__), "assets", "test2.csv"), None, 6, None, None),
        ("test3.csv", join(dirname(__file__), "assets"), 6, None, None),
        (join(dirname(__file__), "assets", "test3.csv"), None, 6, None, None),
        ("test4.csv", join(dirname(__file__), "assets"), -1, CsvParamsDataFileInvalid, "Invalid data"),
        (join(dirname(__file__), "assets", "test4.csv"), None, -1, CsvParamsDataFileInvalid, "Invalid data"),
        ("test5.csv", join(dirname(__file__), "assets"), 6, None, None),
        (join(dirname(__file__), "assets", "test5.csv"), None, 6, None, None),
        ("test-does-not-exist.csv", join(dirname(__file__), "assets"), -1, CsvParamsDataFileNotFound, None),
        (join(dirname(__file__), "assets", "does-not-exist.csv"), None, -1, CsvParamsDataFileNotFound, None),
        ("test-does-not-exist.csv", join(dirname(__file__), "does-not-exist"), -1, CsvParamsDataFileNotFound, None),
        (join(dirname(__file__), "does-not-exist", "does-not-exist.csv"), None, -1, CsvParamsDataFileNotFound, None),
        ("test1.csv", join(dirname(__file__), "does-not-exist"), -1, CsvParamsDataFileNotFound, None),
        (join(dirname(__file__), "does-not-exist", "test1.csv"), None, -1, CsvParamsDataFileNotFound, None),
        (None, join(dirname(__file__), "assets"), -1, CsvParamsDataFileInvalid, None),
        (None, None, -1, CsvParamsDataFileInvalid, None),
    ],
)
def test_csv_reader(
    csv_file: str,
    base_dir: Optional[str],
    expect_lines: Optional[int],
    expect_exception: Optional[Type[Exception]],
    expect_message: Optional[str],
) -> None:
    """
    This test case tests several CSV reading scenarios (by parametrization). CSV test files are in the ``tests/assets``
    folder. The tests target the :meth:`_ptcsvp.parametrize.read_csv` method.

    :param csv_file: The file to test with
    :param base_dir: The base dir to load the :attr:`csv_file` from
    :param expect_lines: Expected read lines from the CSV file
    :param expect_exception: Expected exception when running the method
    :param expect_message: Expected exception message when running the method
    """

    if expect_exception is not None:
        with pytest.raises(expect_exception) as raised_exception:
            read_csv(base_dir, csv_file, CsvParamsDefaultDialect)
        if expect_message is not None:
            assert raised_exception.value.args[0] == expect_message
    else:
        csv_lines = read_csv(base_dir, csv_file, CsvParamsDefaultDialect)
        assert len(csv_lines) == expect_lines
