# pylint:disable=unused-variable
# pylint:disable=unused-argument
# pylint:disable=redefined-outer-name


from typing import AsyncIterator

import pytest
from aioresponses import aioresponses
from faker import Faker
from hypothesis import HealthCheck, given, settings
from hypothesis import strategies as st
from models_library.clusters import ClusterID
from models_library.projects import ProjectID
from models_library.projects_pipeline import ComputationTask
from models_library.projects_state import RunningState
from models_library.users import UserID
from simcore_service_webserver import director_v2_api
from simcore_service_webserver.director_v2_models import (
    ClusterCreate,
    ClusterPatch,
    ClusterPing,
)


@pytest.fixture()
async def mocked_director_v2(
    director_v2_service_mock: aioresponses,
) -> AsyncIterator[aioresponses]:
    yield director_v2_service_mock


@pytest.fixture
def user_id(faker: Faker) -> UserID:
    return UserID(faker.pyint(min_value=1))


@pytest.fixture
def project_id(faker: Faker) -> ProjectID:
    return ProjectID(faker.uuid4())


@pytest.fixture
def cluster_id(faker: Faker) -> ClusterID:
    return ClusterID(faker.pyint(min_value=0))


async def test_create_pipeline(
    mocked_director_v2, client, user_id: UserID, project_id: ProjectID
):
    task_out = await director_v2_api.create_or_update_pipeline(
        client.app, user_id, project_id
    )
    assert task_out
    assert isinstance(task_out, dict)
    assert task_out["state"] == RunningState.NOT_STARTED


async def test_get_computation_task(
    mocked_director_v2,
    client,
    user_id: UserID,
    project_id: ProjectID,
):
    task_out = await director_v2_api.get_computation_task(
        client.app, user_id, project_id
    )
    assert task_out
    assert isinstance(task_out, ComputationTask)
    assert task_out.state == RunningState.NOT_STARTED


async def test_delete_pipeline(
    mocked_director_v2, client, user_id: UserID, project_id: ProjectID
):
    await director_v2_api.delete_pipeline(client.app, user_id, project_id)


@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
@given(cluster_create=st.builds(ClusterCreate))
async def test_create_cluster(
    mocked_director_v2, client, user_id: UserID, cluster_create
):
    created_cluster = await director_v2_api.create_cluster(
        client.app, user_id=user_id, new_cluster=cluster_create
    )
    assert created_cluster is not None
    assert isinstance(created_cluster, dict)
    assert "id" in created_cluster


async def test_list_clusters(mocked_director_v2, client, user_id: UserID):
    list_of_clusters = await director_v2_api.list_clusters(client.app, user_id=user_id)
    assert isinstance(list_of_clusters, list)
    assert len(list_of_clusters) > 0


async def test_get_cluster(
    mocked_director_v2, client, user_id: UserID, cluster_id: ClusterID
):
    cluster = await director_v2_api.get_cluster(
        client.app, user_id=user_id, cluster_id=cluster_id
    )
    assert isinstance(cluster, dict)
    assert cluster["id"] == cluster_id


async def test_get_cluster_details(
    mocked_director_v2, client, user_id: UserID, cluster_id: ClusterID
):
    cluster_details = await director_v2_api.get_cluster_details(
        client.app, user_id=user_id, cluster_id=cluster_id
    )
    assert isinstance(cluster_details, dict)


@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
@given(cluster_patch=st.from_type(ClusterPatch))
async def test_update_cluster(
    mocked_director_v2, client, user_id: UserID, cluster_id: ClusterID, cluster_patch
):
    print(f"--> updating cluster with {cluster_patch=}")
    updated_cluster = await director_v2_api.update_cluster(
        client.app, user_id=user_id, cluster_id=cluster_id, cluster_patch=cluster_patch
    )
    assert isinstance(updated_cluster, dict)
    assert updated_cluster["id"] == cluster_id


async def test_delete_cluster(
    mocked_director_v2, client, user_id: UserID, cluster_id: ClusterID
):
    await director_v2_api.delete_cluster(
        client.app, user_id=user_id, cluster_id=cluster_id
    )


@settings(suppress_health_check=[HealthCheck.function_scoped_fixture])
@given(cluster_ping=st.builds(ClusterPing))
async def test_ping_cluster(mocked_director_v2, client, cluster_ping: ClusterPing):
    await director_v2_api.ping_cluster(client.app, cluster_ping=cluster_ping)


async def test_ping_specific_cluster(
    mocked_director_v2, client, user_id: UserID, cluster_id: ClusterID
):
    await director_v2_api.ping_specific_cluster(
        client.app, user_id=user_id, cluster_id=cluster_id
    )

[((728, 744), 'pytest.fixture', 'pytest.fixture', ([], {}), '()\n', (742, 744), False, 'import pytest\n'), ((2065, 2134), 'hypothesis.settings', 'settings', ([], {'suppress_health_check': '[HealthCheck.function_scoped_fixture]'}), '(suppress_health_check=[HealthCheck.function_scoped_fixture])\n', (2073, 2134), False, 'from hypothesis import HealthCheck, given, settings\n'), ((3362, 3431), 'hypothesis.settings', 'settings', ([], {'suppress_health_check': '[HealthCheck.function_scoped_fixture]'}), '(suppress_health_check=[HealthCheck.function_scoped_fixture])\n', (3370, 3431), False, 'from hypothesis import HealthCheck, given, settings\n'), ((4121, 4190), 'hypothesis.settings', 'settings', ([], {'suppress_health_check': '[HealthCheck.function_scoped_fixture]'}), '(suppress_health_check=[HealthCheck.function_scoped_fixture])\n', (4129, 4190), False, 'from hypothesis import HealthCheck, given, settings\n'), ((1321, 1395), 'simcore_service_webserver.director_v2_api.create_or_update_pipeline', 'director_v2_api.create_or_update_pipeline', (['client.app', 'user_id', 'project_id'], {}), '(client.app, user_id, project_id)\n', (1362, 1395), False, 'from simcore_service_webserver import director_v2_api\n'), ((1672, 1741), 'simcore_service_webserver.director_v2_api.get_computation_task', 'director_v2_api.get_computation_task', (['client.app', 'user_id', 'project_id'], {}), '(client.app, user_id, project_id)\n', (1708, 1741), False, 'from simcore_service_webserver import director_v2_api\n'), ((1997, 2061), 'simcore_service_webserver.director_v2_api.delete_pipeline', 'director_v2_api.delete_pipeline', (['client.app', 'user_id', 'project_id'], {}), '(client.app, user_id, project_id)\n', (2028, 2061), False, 'from simcore_service_webserver import director_v2_api\n'), ((2309, 2401), 'simcore_service_webserver.director_v2_api.create_cluster', 'director_v2_api.create_cluster', (['client.app'], {'user_id': 'user_id', 'new_cluster': 'cluster_create'}), '(client.app, user_id=user_id, new_cluster=\n    cluster_create)\n', (2339, 2401), False, 'from simcore_service_webserver import director_v2_api\n'), ((2157, 2181), 'hypothesis.strategies.builds', 'st.builds', (['ClusterCreate'], {}), '(ClusterCreate)\n', (2166, 2181), True, 'from hypothesis import strategies as st\n'), ((2636, 2694), 'simcore_service_webserver.director_v2_api.list_clusters', 'director_v2_api.list_clusters', (['client.app'], {'user_id': 'user_id'}), '(client.app, user_id=user_id)\n', (2665, 2694), False, 'from simcore_service_webserver import director_v2_api\n'), ((2902, 2981), 'simcore_service_webserver.director_v2_api.get_cluster', 'director_v2_api.get_cluster', (['client.app'], {'user_id': 'user_id', 'cluster_id': 'cluster_id'}), '(client.app, user_id=user_id, cluster_id=cluster_id)\n', (2929, 2981), False, 'from simcore_service_webserver import director_v2_api\n'), ((3212, 3304), 'simcore_service_webserver.director_v2_api.get_cluster_details', 'director_v2_api.get_cluster_details', (['client.app'], {'user_id': 'user_id', 'cluster_id': 'cluster_id'}), '(client.app, user_id=user_id, cluster_id\n    =cluster_id)\n', (3247, 3304), False, 'from simcore_service_webserver import director_v2_api\n'), ((3686, 3802), 'simcore_service_webserver.director_v2_api.update_cluster', 'director_v2_api.update_cluster', (['client.app'], {'user_id': 'user_id', 'cluster_id': 'cluster_id', 'cluster_patch': 'cluster_patch'}), '(client.app, user_id=user_id, cluster_id=\n    cluster_id, cluster_patch=cluster_patch)\n', (3716, 3802), False, 'from simcore_service_webserver import director_v2_api\n'), ((3453, 3479), 'hypothesis.strategies.from_type', 'st.from_type', (['ClusterPatch'], {}), '(ClusterPatch)\n', (3465, 3479), True, 'from hypothesis import strategies as st\n'), ((4021, 4108), 'simcore_service_webserver.director_v2_api.delete_cluster', 'director_v2_api.delete_cluster', (['client.app'], {'user_id': 'user_id', 'cluster_id': 'cluster_id'}), '(client.app, user_id=user_id, cluster_id=\n    cluster_id)\n', (4051, 4108), False, 'from simcore_service_webserver import director_v2_api\n'), ((4329, 4396), 'simcore_service_webserver.director_v2_api.ping_cluster', 'director_v2_api.ping_cluster', (['client.app'], {'cluster_ping': 'cluster_ping'}), '(client.app, cluster_ping=cluster_ping)\n', (4357, 4396), False, 'from simcore_service_webserver import director_v2_api\n'), ((4211, 4233), 'hypothesis.strategies.builds', 'st.builds', (['ClusterPing'], {}), '(ClusterPing)\n', (4220, 4233), True, 'from hypothesis import strategies as st\n'), ((4521, 4614), 'simcore_service_webserver.director_v2_api.ping_specific_cluster', 'director_v2_api.ping_specific_cluster', (['client.app'], {'user_id': 'user_id', 'cluster_id': 'cluster_id'}), '(client.app, user_id=user_id,\n    cluster_id=cluster_id)\n', (4558, 4614), False, 'from simcore_service_webserver import director_v2_api\n')]