"""Tests for alive.network.identity — agent identity management."""

import json
import tempfile
from pathlib import Path
from unittest.mock import patch

import pytest


@pytest.fixture
def tmp_home(tmp_path):
    """Provide a temporary ALIVE_HOME."""
    with patch("alive.network.identity._identity_path", return_value=tmp_path / "identity.json"):
        yield tmp_path


class TestGetOrCreateIdentity:
    def test_creates_new_identity(self, tmp_home):
        from alive.network.identity import get_or_create_identity

        identity = get_or_create_identity()
        assert identity["agent_id"].startswith("alp-")
        assert identity["alias"] is None
        assert identity["alp_version"] == "0.1.0"
        assert "alive_version" in identity
        assert "created_at" in identity

    def test_persists_to_disk(self, tmp_home):
        from alive.network.identity import get_or_create_identity

        identity = get_or_create_identity()
        path = tmp_home / "identity.json"
        assert path.exists()
        loaded = json.loads(path.read_text())
        assert loaded["agent_id"] == identity["agent_id"]

    def test_loads_existing(self, tmp_home):
        from alive.network.identity import get_or_create_identity

        # Create one
        first = get_or_create_identity()
        # Load it again
        second = get_or_create_identity()
        assert first["agent_id"] == second["agent_id"]

    def test_unique_ids(self, tmp_path):
        """Two fresh identities get different IDs."""
        from alive.network.identity import get_or_create_identity

        path1 = tmp_path / "id1.json"
        path2 = tmp_path / "id2.json"

        with patch("alive.network.identity._identity_path", return_value=path1):
            id1 = get_or_create_identity()
        with patch("alive.network.identity._identity_path", return_value=path2):
            id2 = get_or_create_identity()

        assert id1["agent_id"] != id2["agent_id"]


class TestSetAlias:
    def test_sets_alias(self, tmp_home):
        from alive.network.identity import get_or_create_identity, set_alias

        get_or_create_identity()
        set_alias("darsh")
        path = tmp_home / "identity.json"
        loaded = json.loads(path.read_text())
        assert loaded["alias"] == "darsh"

    def test_overwrites_alias(self, tmp_home):
        from alive.network.identity import get_or_create_identity, set_alias

        get_or_create_identity()
        set_alias("first")
        set_alias("second")
        path = tmp_home / "identity.json"
        loaded = json.loads(path.read_text())
        assert loaded["alias"] == "second"


class TestGetAgentCard:
    def test_returns_card_structure(self, tmp_home):
        from alive.network.identity import get_or_create_identity, get_agent_card

        get_or_create_identity()
        with patch("alive.core.skill_registry.get_registry") as mock_reg, \
             patch("alive.integrations.get_available_integrations", return_value={}):
            mock_reg.return_value.list_skills_only.return_value = []
            mock_reg.return_value._skills_dir = tmp_home / "skills"
            card = get_agent_card()

        assert "agent_id" in card
        assert "alias" in card
        assert "skills" in card
        assert "skill_count" in card
        assert "integrations" in card
        assert "alp_version" in card
        assert "uptime_seconds" in card

    def test_includes_configured_integrations(self, tmp_home):
        from alive.network.identity import get_or_create_identity, get_agent_card

        get_or_create_identity()
        intg = {
            "web_search": {"configured": True},
            "telegram": {"configured": False},
            "browser": {"configured": True},
        }
        with patch("alive.core.skill_registry.get_registry") as mock_reg, \
             patch("alive.integrations.get_available_integrations", return_value=intg):
            mock_reg.return_value.list_skills_only.return_value = []
            mock_reg.return_value._skills_dir = tmp_home / "skills"
            card = get_agent_card()

        assert "web_search" in card["integrations"]
        assert "browser" in card["integrations"]
        assert "telegram" not in card["integrations"]

    def test_skill_count_matches(self, tmp_home):
        from alive.network.identity import get_or_create_identity, get_agent_card
        from alive.core.skill_registry import SkillInfo

        get_or_create_identity()
        skills = [
            SkillInfo(name="a", description="A"),
            SkillInfo(name="b", description="B"),
        ]
        skills_dir = tmp_home / "skills"
        skills_dir.mkdir(parents=True, exist_ok=True)
        with patch("alive.core.skill_registry.get_registry") as mock_reg, \
             patch("alive.integrations.get_available_integrations", return_value={}):
            mock_reg.return_value.list_skills_only.return_value = skills
            mock_reg.return_value._skills_dir = skills_dir
            card = get_agent_card()

        assert card["skill_count"] == 2
        assert len(card["skills"]) == 2
