"""Tests for ArtifactRegistry."""

import hashlib
import json
from pathlib import Path

import pytest

from dpe.artifacts.registry import ArtifactRegistry
from dpe.engine.states import Stage


@pytest.fixture
def run_dir(tmp_path: Path) -> Path:
    return tmp_path / "test_run"


@pytest.fixture
def registry(run_dir: Path) -> ArtifactRegistry:
    return ArtifactRegistry(run_dir)


class TestWriteStageArtifact:
    def test_writes_file(self, registry: ArtifactRegistry, run_dir: Path) -> None:
        registry.write_stage_artifact(Stage.INPUT_NORMALIZE, "test content")
        path = run_dir / "00_input_normalized.md"
        assert path.exists()
        assert path.read_text(encoding="utf-8") == "test content"

    def test_returns_record(self, registry: ArtifactRegistry) -> None:
        record = registry.write_stage_artifact(Stage.IDEATION_A, "idea a content")
        assert record.filename == "10_ideation_a.md"
        assert record.stage == "IDEATION_A"
        assert record.size_bytes == len(b"idea a content")

    def test_sha256_correct(self, registry: ArtifactRegistry) -> None:
        content = "hash test content"
        record = registry.write_stage_artifact(Stage.SYNTHESIS, content)
        expected = hashlib.sha256(content.encode()).hexdigest()
        assert record.sha256 == expected

    def test_artifacts_tracked(self, registry: ArtifactRegistry) -> None:
        registry.write_stage_artifact(Stage.INPUT_NORMALIZE, "a")
        registry.write_stage_artifact(Stage.IDEATION_A, "b")
        assert len(registry.artifacts) == 2


class TestWriteManifest:
    def test_writes_json(self, registry: ArtifactRegistry, run_dir: Path) -> None:
        manifest = {"run_id": "test123", "stop_reason": "completed"}
        path = registry.write_manifest(manifest)
        assert path.exists()
        loaded = json.loads(path.read_text(encoding="utf-8"))
        assert loaded["run_id"] == "test123"


class TestWriteArtifactIndex:
    def test_writes_index(self, registry: ArtifactRegistry, run_dir: Path) -> None:
        registry.write_stage_artifact(Stage.INPUT_NORMALIZE, "content")
        path = registry.write_artifact_index()
        assert path.exists()
        index = json.loads(path.read_text(encoding="utf-8"))
        assert len(index) == 1
        assert index[0]["filename"] == "00_input_normalized.md"


class TestPathSafety:
    def test_rejects_path_traversal(self, registry: ArtifactRegistry) -> None:
        with pytest.raises(ValueError, match="Invalid artifact filename"):
            registry._write(filename="../escape.md", stage="TEST", content="bad")

    def test_rejects_backslash_traversal(self, registry: ArtifactRegistry) -> None:
        with pytest.raises(ValueError, match="Invalid artifact filename"):
            registry._write(filename="..\\escape.md", stage="TEST", content="bad")
