"""Tests for WES models."""

from __future__ import annotations

from ai4gh.specs.wes.models import (
    RunDescription,
    RunId,
    RunListResponse,
    RunLog,
    RunRequest,
    RunStatus,
    ServiceInfo,
    State,
)


class TestState:
    def test_enum_values(self) -> None:
        assert State.UNKNOWN == "UNKNOWN"
        assert State.QUEUED == "QUEUED"
        assert State.RUNNING == "RUNNING"
        assert State.COMPLETE == "COMPLETE"
        assert State.EXECUTOR_ERROR == "EXECUTOR_ERROR"
        assert State.SYSTEM_ERROR == "SYSTEM_ERROR"
        assert State.CANCELED == "CANCELED"
        assert State.CANCELING == "CANCELING"

    def test_from_string(self) -> None:
        assert State("RUNNING") is State.RUNNING


class TestRunLog:
    def test_minimal(self) -> None:
        log = RunLog()
        assert log.name is None
        assert log.cmd is None
        assert log.exit_code is None

    def test_full(self) -> None:
        log = RunLog(
            name="step1",
            cmd=["echo", "hello"],
            start_time="2024-01-01T00:00:00Z",
            end_time="2024-01-01T00:01:00Z",
            stdout="/logs/stdout",
            stderr="/logs/stderr",
            exit_code=0,
        )
        assert log.name == "step1"
        assert log.cmd == ["echo", "hello"]
        assert log.exit_code == 0


class TestRunRequest:
    def test_minimal(self) -> None:
        req = RunRequest()
        assert req.workflow_url is None
        assert req.workflow_type is None

    def test_full(self) -> None:
        req = RunRequest(
            workflow_url="https://example.com/workflow.cwl",
            workflow_type="CWL",
            workflow_type_version="v1.0",
            workflow_params={"input": "data.bam"},
            tags={"project": "test"},
        )
        assert req.workflow_url == "https://example.com/workflow.cwl"
        assert req.workflow_type == "CWL"
        assert req.tags == {"project": "test"}


class TestRunStatus:
    def test_creation(self) -> None:
        status = RunStatus(run_id="run-1", state=State.RUNNING)
        assert status.run_id == "run-1"
        assert status.state is State.RUNNING

    def test_from_dict(self) -> None:
        status = RunStatus.model_validate({"run_id": "run-2", "state": "COMPLETE"})
        assert status.state is State.COMPLETE


class TestRunListResponse:
    def test_empty(self) -> None:
        resp = RunListResponse()
        assert resp.runs is None
        assert resp.next_page_token is None

    def test_with_runs(self) -> None:
        resp = RunListResponse(
            runs=[RunStatus(run_id="r1", state=State.RUNNING)],
            next_page_token="token-2",
        )
        assert len(resp.runs) == 1
        assert resp.next_page_token == "token-2"


class TestRunDescription:
    def test_minimal(self) -> None:
        desc = RunDescription(run_id="run-1")
        assert desc.run_id == "run-1"
        assert desc.state is None
        assert desc.run_log is None
        assert desc.task_logs is None

    def test_full(self) -> None:
        desc = RunDescription(
            run_id="run-1",
            state=State.COMPLETE,
            request=RunRequest(workflow_url="https://example.com/wf.cwl"),
            run_log=RunLog(name="main", exit_code=0),
            task_logs=[RunLog(name="task1", exit_code=0)],
            outputs={"output1": "s3://bucket/result.bam"},
        )
        assert desc.state is State.COMPLETE
        assert desc.run_log.exit_code == 0
        assert len(desc.task_logs) == 1
        assert "output1" in desc.outputs


class TestRunId:
    def test_creation(self) -> None:
        rid = RunId(run_id="run-123")
        assert rid.run_id == "run-123"


class TestServiceInfo:
    def test_minimal(self) -> None:
        info = ServiceInfo()
        assert info.supported_wes_versions is None

    def test_full(self) -> None:
        info = ServiceInfo(
            supported_wes_versions=["1.0.0", "1.1.0"],
            supported_filesystem_protocols=["s3", "gs"],
            auth_instructions_url="https://example.com/auth",
        )
        assert "1.1.0" in info.supported_wes_versions
        assert "s3" in info.supported_filesystem_protocols


class TestExtraFields:
    def test_allows_extra(self) -> None:
        log = RunLog.model_validate({"name": "step1", "custom_field": "custom_value"})
        assert log.name == "step1"
        assert log.custom_field == "custom_value"
