"""Tests for Ultraplan Mode — Issue #840."""
import json
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))

from tools.ultraplan import (
    Phase, Stream, Ultraplan,
    create_ultraplan, save_ultraplan, load_ultraplan,
    generate_daily_cron_prompt
)


class TestPhase:
    def test_creation(self):
        phase = Phase(id="A1", name="Setup", artifact="config.yaml")
        assert phase.id == "A1"
        assert phase.status == "pending"
    
    def test_dependencies(self):
        phase = Phase(id="A2", name="Build", dependencies=["A1"])
        assert "A1" in phase.dependencies


class TestStream:
    def test_progress_empty(self):
        stream = Stream(id="A", name="Stream A")
        assert stream.progress == 0.0
    
    def test_progress_partial(self):
        stream = Stream(id="A", name="Stream A", phases=[
            Phase(id="A1", name="P1", status="done"),
            Phase(id="A2", name="P2", status="pending"),
        ])
        assert stream.progress == 0.5
    
    def test_current_phase(self):
        stream = Stream(id="A", name="Stream A", phases=[
            Phase(id="A1", name="P1", status="done"),
            Phase(id="A2", name="P2", status="active"),
            Phase(id="A3", name="P3", status="pending"),
        ])
        assert stream.current_phase.id == "A2"


class TestUltraplan:
    def test_to_markdown(self):
        plan = Ultraplan(
            date="20260415",
            mission="Test mission",
            streams=[
                Stream(id="A", name="Stream A", phases=[
                    Phase(id="A1", name="Phase 1", artifact="file.txt"),
                ]),
            ],
        )
        md = plan.to_markdown()
        assert "# Ultraplan: 20260415" in md
        assert "Test mission" in md
        assert "Stream A" in md
    
    def test_progress(self):
        plan = Ultraplan(
            date="20260415",
            mission="Test",
            streams=[
                Stream(id="A", name="A", status="done", phases=[
                    Phase(id="A1", name="P1", status="done"),
                ]),
                Stream(id="B", name="B", status="pending", phases=[
                    Phase(id="B1", name="P1", status="pending"),
                ]),
            ],
        )
        assert plan.progress == 0.5
    
    def test_to_dict(self):
        plan = Ultraplan(date="20260415", mission="Test")
        d = plan.to_dict()
        assert d["date"] == "20260415"
        assert d["mission"] == "Test"


class TestCreateUltraplan:
    def test_default_date(self):
        plan = create_ultraplan(mission="Test")
        assert len(plan.date) == 8  # YYYYMMDD
    
    def test_with_streams(self):
        plan = create_ultraplan(
            mission="Test",
            streams=[
                {
                    "id": "A",
                    "name": "Stream A",
                    "phases": [
                        {"id": "A1", "name": "Setup", "artifact": "config.yaml"},
                        {"id": "A2", "name": "Build", "dependencies": ["A1"]},
                    ],
                },
            ],
        )
        assert len(plan.streams) == 1
        assert len(plan.streams[0].phases) == 2
        assert plan.streams[0].phases[1].dependencies == ["A1"]


class TestSaveLoad:
    def test_roundtrip(self, tmp_path):
        plan = create_ultraplan(
            date="20260415",
            mission="Test roundtrip",
            streams=[{"id": "A", "name": "Stream A"}],
        )
        
        save_ultraplan(plan, base_dir=tmp_path)
        loaded = load_ultraplan("20260415", base_dir=tmp_path)
        
        assert loaded is not None
        assert loaded.date == "20260415"
        assert loaded.mission == "Test roundtrip"
    
    def test_nonexistent_returns_none(self, tmp_path):
        assert load_ultraplan("99999999", base_dir=tmp_path) is None


class TestCronPrompt:
    def test_has_required_elements(self):
        prompt = generate_daily_cron_prompt()
        assert "Ultraplan" in prompt
        assert "streams" in prompt.lower()
        assert "Gitea" in prompt


if __name__ == "__main__":
    import pytest
    pytest.main([__file__, "-v"])
