"""Tests for brokr SDK get() function."""

import pytest

import brokr
from brokr.sdk import get
from brokr.store import BrokrError, load_store, save_store


def _init_store(tmp_path, monkeypatch, passphrase="secret"):
    monkeypatch.setenv("BROKR_DIR", str(tmp_path))
    monkeypatch.setenv("BROKR_PASSPHRASE", passphrase)
    save_store({"secrets": {}}, passphrase, store_dir=tmp_path)


# --- V1 tests (preserved exactly) ---


class TestGet:
    def test_retrieve_stored_secret(self, tmp_path, monkeypatch):
        _init_store(tmp_path, monkeypatch)
        data = load_store("secret", store_dir=tmp_path)
        data["secrets"]["API_KEY"] = "sk-abc123"
        save_store(data, "secret", store_dir=tmp_path)

        assert get("API_KEY") == "sk-abc123"

    def test_explicit_passphrase(self, tmp_path, monkeypatch):
        monkeypatch.setenv("BROKR_DIR", str(tmp_path))
        monkeypatch.delenv("BROKR_PASSPHRASE", raising=False)
        save_store({"secrets": {"TOKEN": "t-999"}}, "mypass", store_dir=tmp_path)

        assert get("TOKEN", passphrase="mypass") == "t-999"

    def test_no_passphrase_raises(self, tmp_path, monkeypatch):
        monkeypatch.setenv("BROKR_DIR", str(tmp_path))
        monkeypatch.delenv("BROKR_PASSPHRASE", raising=False)

        with pytest.raises(BrokrError, match="No passphrase"):
            get("ANY_KEY")

    def test_missing_key_raises(self, tmp_path, monkeypatch):
        _init_store(tmp_path, monkeypatch)

        with pytest.raises(KeyError):
            get("NONEXISTENT")

    def test_importable_from_brokr(self):
        assert brokr.get is get
        assert brokr.BrokrError is BrokrError


# --- V1.5 project scoping tests ---


def _make_store_with_projects(tmp_path, monkeypatch, passphrase="secret"):
    monkeypatch.setenv("BROKR_DIR", str(tmp_path))
    monkeypatch.setenv("BROKR_PASSPHRASE", passphrase)
    data = {
        "secrets": {
            "API_KEY": "sk-123",
            "TOKEN": "tok-456",
            "OTHER": "other-val",
        },
        "projects": {
            "my-app": {
                "secrets": ["API_KEY", "TOKEN"],
                "agents": {
                    "deploy-bot": ["TOKEN"],
                    "research-agent": ["API_KEY"],
                },
            },
            "infra": {
                "secrets": ["TOKEN"],
                "agents": {},
            },
        },
    }
    save_store(data, passphrase, store_dir=tmp_path)


class TestGetWithProject:
    def test_returns_linked_secret(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        assert get("API_KEY", project="my-app") == "sk-123"

    def test_rejects_unlinked_secret(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        with pytest.raises(KeyError, match="not linked"):
            get("OTHER", project="my-app")

    def test_unknown_project(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        with pytest.raises(KeyError):
            get("API_KEY", project="ghost")

    def test_secret_in_store_but_not_project(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        with pytest.raises(KeyError):
            get("OTHER", project="infra")


class TestGetWithAgent:
    def test_returns_granted_secret(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        assert get("TOKEN", agent="deploy-bot", project="my-app") == "tok-456"

    def test_rejects_ungranted_secret(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        with pytest.raises(PermissionError, match="not granted"):
            get("API_KEY", agent="deploy-bot", project="my-app")

    def test_agent_without_project_raises(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        with pytest.raises(BrokrError, match="project is required"):
            get("TOKEN", agent="deploy-bot")

    def test_unknown_agent_raises(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        with pytest.raises(BrokrError, match="not found"):
            get("TOKEN", agent="ghost", project="my-app")

    def test_cross_project_isolation(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        # deploy-bot exists in my-app but not in infra
        with pytest.raises(BrokrError, match="not found"):
            get("TOKEN", agent="deploy-bot", project="infra")


class TestBackwardCompat:
    def test_old_store_without_projects(self, tmp_path, monkeypatch):
        monkeypatch.setenv("BROKR_DIR", str(tmp_path))
        monkeypatch.setenv("BROKR_PASSPHRASE", "secret")
        save_store({"secrets": {"KEY": "val"}}, "secret", store_dir=tmp_path)
        assert get("KEY") == "val"

    def test_default_get_ignores_projects(self, tmp_path, monkeypatch):
        _make_store_with_projects(tmp_path, monkeypatch)
        # Without project param, get() returns any secret
        assert get("OTHER") == "other-val"
