"""Tests for openspec Pydantic models."""

import json
from pathlib import Path

from hangar.models.openspec import (
    OpenSpecArtifact,
    OpenSpecArtifactContent,
    OpenSpecChangeList,
    OpenSpecChangeStatus,
    OpenSpecChangeSummary,
)

FIXTURES = Path(__file__).parent / "fixtures"


def test_parse_openspec_list_json() -> None:
    """Parse the full openspec list --json output."""
    data = json.loads((FIXTURES / "openspec_list.json").read_text())
    change_list = OpenSpecChangeList.from_json(data)

    assert len(change_list.changes) > 0
    for change in change_list.changes:
        assert change.name
        assert change.status in ("in-progress", "complete", "draft", "applied")


def test_parse_openspec_status_json() -> None:
    """Parse the openspec status --json output."""
    data = json.loads((FIXTURES / "openspec_status.json").read_text())
    status = OpenSpecChangeStatus.model_validate(data)

    assert status.change_name == "mvp-foundation"
    assert status.schema_name == "spec-driven"
    assert len(status.artifacts) > 0
    for artifact in status.artifacts:
        assert artifact.id
        assert artifact.output_path


def test_change_summary_fields() -> None:
    """ChangeSummary should parse camelCase fields correctly."""
    data = {
        "name": "test-change",
        "completedTasks": 5,
        "totalTasks": 10,
        "lastModified": "2026-02-07T00:50:37.975Z",
        "status": "in-progress",
    }
    summary = OpenSpecChangeSummary.model_validate(data)
    assert summary.name == "test-change"
    assert summary.completed_tasks == 5
    assert summary.total_tasks == 10
    assert summary.status == "in-progress"


def test_artifact_content_model() -> None:
    """ArtifactContent should hold rendered markdown."""
    content = OpenSpecArtifactContent(
        id="proposal",
        output_path="proposal.md",
        status="done",
        content="# My Proposal\n\nSome content here.",
    )
    assert content.id == "proposal"
    assert "# My Proposal" in content.content


def test_artifact_alias_handling() -> None:
    """Artifact model should handle both camelCase and snake_case."""
    # From JSON (camelCase)
    from_json = OpenSpecArtifact.model_validate(
        {"id": "specs", "outputPath": "specs/**/*.md", "status": "done"}
    )
    assert from_json.output_path == "specs/**/*.md"

    # From Python (snake_case)
    from_python = OpenSpecArtifact(id="specs", output_path="specs/**/*.md", status="done")
    assert from_python.output_path == "specs/**/*.md"
