"""Tests for TRS models."""

from __future__ import annotations

from ai4gh.specs.trs.models import (
    DescriptorType,
    FileWrapper,
    ImageData,
    Tool,
    ToolClass,
    ToolSearchResponse,
    ToolVersion,
)


class TestDescriptorType:
    def test_enum_values(self) -> None:
        assert DescriptorType.CWL == "CWL"
        assert DescriptorType.WDL == "WDL"
        assert DescriptorType.NFL == "NFL"
        assert DescriptorType.GALAXY == "GALAXY"
        assert DescriptorType.SMK == "SMK"
        assert DescriptorType.JUPYTER == "JUPYTER"
        assert DescriptorType.OTHER == "OTHER"

    def test_from_string(self) -> None:
        assert DescriptorType("CWL") is DescriptorType.CWL


class TestToolClass:
    def test_minimal(self) -> None:
        tc = ToolClass()
        assert tc.id is None
        assert tc.name is None

    def test_full(self) -> None:
        tc = ToolClass(id="1", name="Workflow", description="A workflow")
        assert tc.id == "1"
        assert tc.name == "Workflow"


class TestFileWrapper:
    def test_with_content(self) -> None:
        fw = FileWrapper(content="class: Workflow\nsteps: []")
        assert fw.content.startswith("class:")
        assert fw.url is None

    def test_with_url(self) -> None:
        fw = FileWrapper(url="https://example.com/workflow.cwl")
        assert fw.url == "https://example.com/workflow.cwl"

    def test_with_checksum(self) -> None:
        fw = FileWrapper(
            content="data",
            checksum=[{"checksum": "abc123", "type": "sha256"}],
        )
        assert len(fw.checksum) == 1


class TestImageData:
    def test_minimal(self) -> None:
        img = ImageData()
        assert img.image_name is None
        assert img.size is None

    def test_full(self) -> None:
        img = ImageData(
            registry_host="docker.io",
            image_name="biocontainers/bwa",
            size=524288000,
            updated="2024-01-01T00:00:00Z",
            image_type="Docker",
        )
        assert img.registry_host == "docker.io"
        assert img.size == 524288000


class TestToolVersion:
    def test_minimal(self) -> None:
        tv = ToolVersion()
        assert tv.id is None
        assert tv.is_production is None

    def test_full(self) -> None:
        tv = ToolVersion(
            id="v1.0",
            name="Release 1.0",
            url="https://dockstore.org/tool/1/v1.0",
            is_production=True,
            descriptor_type=[DescriptorType.CWL, DescriptorType.WDL],
            author=["Alice", "Bob"],
            meta_version="2024-01-01",
            signed=False,
            images=[ImageData(image_name="tool:1.0", registry_host="docker.io")],
        )
        assert tv.is_production is True
        assert len(tv.descriptor_type) == 2
        assert tv.author == ["Alice", "Bob"]
        assert len(tv.images) == 1


class TestTool:
    def test_minimal(self) -> None:
        tool = Tool()
        assert tool.id is None
        assert tool.versions is None

    def test_full(self) -> None:
        tool = Tool(
            id="tool-1",
            url="https://dockstore.org/tool/1",
            name="BWA-MEM",
            organization="biocontainers",
            toolclass=ToolClass(id="1", name="Workflow"),
            description="BWA alignment workflow",
            meta_version="2024-01-01",
            has_checker=False,
            versions=[ToolVersion(id="v1.0", is_production=True)],
            aliases=["bwa", "bwa-mem"],
        )
        assert tool.id == "tool-1"
        assert tool.toolclass.name == "Workflow"
        assert len(tool.versions) == 1
        assert "bwa" in tool.aliases

    def test_from_dict(self) -> None:
        tool = Tool.model_validate(
            {
                "id": "tool-2",
                "name": "GATK",
                "organization": "Broad Institute",
            }
        )
        assert tool.name == "GATK"


class TestToolSearchResponse:
    def test_empty(self) -> None:
        resp = ToolSearchResponse()
        assert resp.tools is None

    def test_with_results(self) -> None:
        resp = ToolSearchResponse(
            tools=[Tool(id="t1"), Tool(id="t2")],
            next_page_token="next",
        )
        assert len(resp.tools) == 2
        assert resp.next_page_token == "next"


class TestExtraFields:
    def test_allows_extra(self) -> None:
        tool = Tool.model_validate({"id": "tool-1", "custom_registry": "dockstore"})
        assert tool.custom_registry == "dockstore"
