"""Tests for prodigy_teams.config — SavedSettings and RootConfig."""

from __future__ import annotations

from pathlib import Path
from uuid import uuid4

import pytest

from prodigy_teams.config import RootConfig, SavedSettings


class TestSavedSettings:
    def test_blank(self):
        s = SavedSettings.blank()
        assert s.broker_host is None
        assert s.project is None
        assert s.task is None
        assert s.action is None
        assert s.agent is None
        assert s.pam_host is None
        assert s.broker_id is None
        assert s.recipes_file is None

    def test_from_file_missing_non_required(self, tmp_path: Path):
        path = tmp_path / "settings.json"
        s = SavedSettings.from_file(path, must_exist=False)
        assert s.broker_host is None

    def test_from_file_missing_required(self, tmp_path: Path):
        path = tmp_path / "settings.json"
        with pytest.raises(FileNotFoundError):
            SavedSettings.from_file(path, must_exist=True)

    def test_roundtrip(self, tmp_path: Path):
        path = tmp_path / "settings.json"
        project_id = uuid4()
        s = SavedSettings(
            broker_host="host.example.com",
            project=project_id,
            pam_host="pam.example.com",
        )
        s.save(path)
        loaded = SavedSettings.from_file(path)
        assert loaded.broker_host == "host.example.com"
        assert loaded.project == project_id
        assert loaded.pam_host == "pam.example.com"

    def test_save_creates_parent_dirs(self, tmp_path: Path):
        path = tmp_path / "a" / "b" / "settings.json"
        s = SavedSettings.blank()
        s.save(path)
        assert path.exists()

    def test_to_json(self):
        pid = uuid4()
        s = SavedSettings(project=pid, broker_host="host")
        d = s.to_json()
        assert d["project"] == str(pid)
        assert d["broker_host"] == "host"
        assert d["task"] is None

    def test_to_json_uuids_are_strings(self):
        s = SavedSettings(
            project=uuid4(),
            task=uuid4(),
            action=uuid4(),
            agent=uuid4(),
            broker_id=uuid4(),
        )
        d = s.to_json()
        for key in ("project", "task", "action", "agent", "broker_id"):
            assert isinstance(d[key], str)

    def test_reset_defaults(self):
        s = SavedSettings(
            project=uuid4(),
            task=uuid4(),
            action=uuid4(),
            agent=uuid4(),
            broker_host="host",
            pam_host="pam",
        )
        s.reset_defaults()
        assert s.project is None
        assert s.task is None
        assert s.action is None
        assert s.agent is None
        # Non-default fields should remain
        assert s.broker_host == "host"
        assert s.pam_host == "pam"

    def test_update_simple_field(self):
        s = SavedSettings.blank()
        result = s.update("broker_host", "new-host")
        assert result == "new-host"
        assert s.broker_host == "new-host"

    def test_update_uuid_field(self):
        s = SavedSettings.blank()
        uid = uuid4()
        result = s.update("project", uid)
        assert result == uid
        assert s.project == uid

    def test_update_host_resets_defaults(self):
        s = SavedSettings(
            pam_host="old.host",
            project=uuid4(),
            task=uuid4(),
            action=uuid4(),
            agent=uuid4(),
        )
        s.update("pam_host", "new.host")
        assert s.pam_host == "new.host"
        assert s.project is None
        assert s.task is None

    def test_update_broker_host_resets_defaults(self):
        s = SavedSettings(
            broker_host="old.host",
            project=uuid4(),
            task=uuid4(),
        )
        s.update("broker_host", "new.host")
        assert s.broker_host == "new.host"
        assert s.project is None

    def test_update_same_host_no_reset(self):
        pid = uuid4()
        s = SavedSettings(pam_host="same.host", project=pid)
        s.update("pam_host", "same.host")
        assert s.project == pid

    def test_update_non_host_field_no_reset(self):
        pid = uuid4()
        new_task = uuid4()
        s = SavedSettings(project=pid)
        s.update("task", new_task)
        assert s.project == pid
        assert s.task == new_task


class TestRootConfig:
    def test_paths(self, tmp_path: Path):
        cfg = RootConfig(config_dir=tmp_path)
        assert cfg.secrets_path == tmp_path / "secrets.json"
        assert cfg.saved_settings_path == tmp_path / "saved-defaults.json"
