"""Collection of tests to ensure correct implementation and track progress. """

from fastapi.testclient import TestClient
import pytest

from ..structs.toilets import Toilets
from ..main import app


@pytest.fixture(scope="module")
def client():
    """Client used to call the app."""
    return TestClient(app)


@pytest.mark.parametrize(
    "location,radius,status_code",
    [
        ({}, None, 422),                # Invalid case: no location at all.
        ([443], None, 422),             # Invalid cases: invalid location.
        ([443, 433], None, 422),             # Invalid cases: invalid location.
    ]
)
def test_invalid_input(client, location, radius, status_code):    # pylint: disable=redefined-outer-name
    """
    Test n°1 : Verify handling of invalid input.

    Args:
        client:
        request:
    """
    response = client.post(
        "/toilets/new",
        params={
            "location": location,
            "radius": radius
        }
    )

    # checks :
    assert response.status_code == status_code


@pytest.mark.parametrize(
    "location,status_code",
    [
        ([48.2270, 7.4370], 200), # Orschwiller.
        ([10.2012, 10.123], 200), # Nigerian desert.
        ([63.989, -19.677], 200), # Hekla volcano, Iceland
    ]
)
def test_no_toilets(client, location, status_code):    # pylint: disable=redefined-outer-name
    """
    Test n°3 : Verify the code finds some toilets in big cities.

    Args:
        client:
        request:
    """
    response = client.post(
        "/toilets/new",
        params={
            "location": location
        }
    )
    toilets_list = [Toilets.model_validate(toilet) for toilet in response.json()]

    # checks :
    assert response.status_code == status_code  # check for successful planning
    assert isinstance(toilets_list, list)  # check that the return type is a list


@pytest.mark.parametrize(
    "location,status_code",
    [
        ([45.7576485, 4.8330241], 200), # Lyon, Bellecour.
        ([-6.913795,  107.60278], 200), # Bandung, train station
        ([-22.970140, -43.18181], 200), # Rio de Janeiro, Copacabana
    ]
)
def test_toilets(client, location, status_code):    # pylint: disable=redefined-outer-name
    """
    Test n°3 : Verify the code finds some toilets in big cities.

    Args:
        client:
        request:
    """
    response = client.post(
        "/toilets/new",
        params={
            "location": location,
            "radius" : 600
        }
    )
    toilets_list = [Toilets.model_validate(toilet) for toilet in response.json()]

    # checks :
    assert response.status_code == status_code  # check for successful planning
    assert isinstance(toilets_list, list)  # check that the return type is a list
    assert len(toilets_list) > 0
