"""Tests for template model and session persistence."""

from pathlib import Path

import pytest

from impakt.template.library import TemplateLibrary
from impakt.template.model import PlotDefinition, SessionState, TemplateSpec
from impakt.template.session import SessionManager


class TestTemplateSpec:
    def test_yaml_round_trip(self):
        template = TemplateSpec(
            name="Test Template",
            version=2,
            description="A test template",
            plots=[
                PlotDefinition(
                    title="Head Acceleration",
                    channel_patterns=["*HEAD*AC*"],
                    x_cursors=(0.0, 0.1),
                )
            ],
            default_cfc=1000,
            criteria=["hic15", "nij"],
            protocol="euro_ncap",
        )

        yaml_str = template.to_yaml()
        restored = TemplateSpec.from_yaml(yaml_str)

        assert restored.name == "Test Template"
        assert restored.version == 2
        assert restored.default_cfc == 1000
        assert len(restored.plots) == 1
        assert restored.plots[0].channel_patterns == ["*HEAD*AC*"]
        assert restored.criteria == ["hic15", "nij"]

    def test_save_and_load(self, tmp_path):
        template = TemplateSpec(name="Saved Test", version=1)
        path = tmp_path / "test.yaml"
        template.save(path)
        assert path.exists()

        loaded = TemplateSpec.load(path)
        assert loaded.name == "Saved Test"


class TestSessionState:
    def test_yaml_round_trip(self):
        state = SessionState(
            template_name="my_template",
            template_version=3,
            test_path="/data/test_001",
            overrides={"cfc": "600", "selected": ["ch1", "ch2"]},
        )
        yaml_str = state.to_yaml()
        restored = SessionState.from_yaml(yaml_str)

        assert restored.template_name == "my_template"
        assert restored.template_version == 3
        assert restored.overrides["cfc"] == "600"

    def test_save_and_load(self, tmp_path):
        state = SessionState(template_name="test")
        path = tmp_path / "session.yaml"
        state.save(path)
        assert path.exists()

        loaded = SessionState.load(path)
        assert loaded.template_name == "test"


class TestTemplateLibrary:
    def test_empty_library(self, tmp_path):
        lib = TemplateLibrary(tmp_path / "templates")
        assert lib.list() == []
        assert len(lib) == 0

    def test_save_and_list(self, tmp_path):
        lib = TemplateLibrary(tmp_path / "templates")
        template = TemplateSpec(name="My Template")
        lib.save(template)
        assert "my_template" in lib.list()
        assert len(lib) == 1

    def test_get(self, tmp_path):
        lib = TemplateLibrary(tmp_path / "templates")
        lib.save(TemplateSpec(name="Getter Test", version=5))
        loaded = lib.get("getter_test")
        assert loaded.name == "Getter Test"
        assert loaded.version == 5

    def test_delete(self, tmp_path):
        lib = TemplateLibrary(tmp_path / "templates")
        lib.save(TemplateSpec(name="To Delete"))
        assert lib.delete("to_delete")
        assert "to_delete" not in lib.list()

    def test_get_missing_raises(self, tmp_path):
        lib = TemplateLibrary(tmp_path / "templates")
        with pytest.raises(FileNotFoundError):
            lib.get("nonexistent")


class TestSessionManager:
    def test_create_and_save(self, tmp_path):
        mgr = SessionManager(tmp_path)
        mgr.state.template_name = "test_tmpl"
        mgr.save()
        assert mgr.has_session
        assert (tmp_path / ".impakt" / "session.yaml").exists()

    def test_load_existing(self, tmp_path):
        # Save
        mgr1 = SessionManager(tmp_path)
        mgr1.state.template_name = "saved_tmpl"
        mgr1.state.overrides = {"key": "value"}
        mgr1.save()

        # Load
        mgr2 = SessionManager(tmp_path)
        assert mgr2.state.template_name == "saved_tmpl"
        assert mgr2.state.overrides["key"] == "value"

    def test_clear(self, tmp_path):
        mgr = SessionManager(tmp_path)
        mgr.save()
        assert mgr.has_session
        mgr.clear()
        assert not mgr.has_session
