"""Tests for cluster discovery."""
import json
import tempfile
from pathlib import Path

import pytest

from greymatter_core.cluster.discovery import (
    ClusterEndpoint,
    discover_all,
    discover_manual,
    discover_tailscale,
)


class TestClusterEndpoint:
    def test_url_format(self):
        ep = ClusterEndpoint(address="100.81.247.14", port=8000)
        assert ep.url == "http://100.81.247.14:8000"

    def test_to_dict(self):
        ep = ClusterEndpoint(address="10.0.0.1", port=9000, name="hub-1", source="manual")
        d = ep.to_dict()
        assert d["address"] == "10.0.0.1"
        assert d["port"] == 9000
        assert d["name"] == "hub-1"


class TestManualDiscovery:
    def test_reads_config_file(self, tmp_path):
        config = tmp_path / "discovery.json"
        config.write_text(json.dumps({
            "endpoints": [
                {"address": "100.81.247.14", "port": 8000, "name": "hub-1"},
                {"address": "10.0.0.2", "port": 9000},
            ]
        }))
        endpoints = discover_manual(config)
        assert len(endpoints) == 2
        assert endpoints[0].address == "100.81.247.14"
        assert endpoints[0].source == "manual"
        assert endpoints[1].port == 9000

    def test_missing_file_returns_empty(self):
        endpoints = discover_manual("/nonexistent/path.json")
        assert endpoints == []

    def test_invalid_json_returns_empty(self, tmp_path):
        config = tmp_path / "bad.json"
        config.write_text("not json")
        endpoints = discover_manual(config)
        assert endpoints == []

    def test_default_port(self, tmp_path):
        config = tmp_path / "discovery.json"
        config.write_text(json.dumps({
            "endpoints": [{"address": "10.0.0.1"}]
        }))
        endpoints = discover_manual(config)
        assert endpoints[0].port == 8000


class TestTailscaleDiscovery:
    def test_no_api_key_returns_empty(self, monkeypatch):
        monkeypatch.delenv("TAILSCALE_API_KEY", raising=False)
        monkeypatch.delenv("TAILSCALE_TAILNET", raising=False)
        endpoints = discover_tailscale()
        assert endpoints == []


class TestDiscoverAll:
    def test_combines_manual_sources(self, tmp_path):
        config = tmp_path / "discovery.json"
        config.write_text(json.dumps({
            "endpoints": [{"address": "10.0.0.1"}]
        }))
        endpoints = discover_all(config_path=config)
        assert len(endpoints) >= 1
        assert endpoints[0].address == "10.0.0.1"

    def test_deduplicates_by_address(self, tmp_path):
        config = tmp_path / "discovery.json"
        config.write_text(json.dumps({
            "endpoints": [
                {"address": "10.0.0.1"},
                {"address": "10.0.0.1"},  # duplicate
            ]
        }))
        endpoints = discover_all(config_path=config)
        assert len(endpoints) == 1

    def test_no_config_returns_empty(self):
        endpoints = discover_all()
        assert endpoints == []
