#!/usr/bin/env python3
"""
Tests for config_factory: create configs and optionally validate with SimpleConfigValidator.

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""
import json
import tempfile
from pathlib import Path

from mcp_proxy_adapter.examples.config_factory import (
    create_full_featured,
    create_http_simple,
    create_http_token,
    create_https_simple,
    create_https_token,
    create_mtls_simple,
    create_mtls_with_roles,
    create_mtls_with_proxy,
)


class TestConfigFactory:
    """Test config_factory presets produce valid structure (server, client, etc.)."""

    def test_http_simple_has_required_sections(self) -> None:
        cfg = create_http_simple(port=8080, log_dir="./logs")
        assert "server" in cfg
        assert cfg["server"]["protocol"] == "http"
        assert cfg["server"]["port"] == 8080
        assert cfg["server"].get("servername") in ("localhost", "0.0.0.0")
        assert "client" in cfg and "registration" in cfg and "auth" in cfg

    def test_http_token_has_auth_tokens(self) -> None:
        cfg = create_http_token(port=8080, api_keys={"admin": "admin-key"})
        assert cfg["auth"].get("use_token") is True
        assert "admin-key" in (cfg["auth"].get("tokens") or {})

    def test_https_simple_has_ssl(self) -> None:
        cfg = create_https_simple(port=8443, cert_dir="./certs", key_dir="./keys")
        assert cfg["server"]["protocol"] == "https"
        assert cfg["server"].get("ssl") is not None

    def test_mtls_simple_has_ssl_and_ca(self) -> None:
        cfg = create_mtls_simple(port=8443, cert_dir="./certs", key_dir="./keys")
        assert cfg["server"]["protocol"] == "mtls"
        ssl = cfg["server"].get("ssl")
        assert ssl is not None
        assert ssl.get("ca") or ssl.get("cert")

    def test_mtls_with_roles_has_auth_roles(self) -> None:
        cfg = create_mtls_with_roles(
            port=8443,
            cert_dir="./certs",
            key_dir="./keys",
            roles={"admin": ["read", "write"]},
        )
        assert cfg["auth"].get("use_roles") is True
        assert (cfg["auth"].get("roles") or {}).get("admin") == ["read", "write"]

    def test_mtls_with_proxy_has_registration_enabled(self) -> None:
        cfg = create_mtls_with_proxy(
            port=8443,
            cert_dir="./certs",
            key_dir="./keys",
            proxy_url="https://127.0.0.1:3005",
            server_id="test-server",
        )
        assert cfg["registration"].get("enabled") is True
        assert "register_url" in (cfg["registration"] or {})

    def test_full_featured_has_token_and_roles(self) -> None:
        cfg = create_full_featured(
            port=8443,
            cert_dir="./certs",
            key_dir="./keys",
            server_id="full-server",
        )
        assert cfg["auth"].get("use_token") is True
        assert cfg["auth"].get("use_roles") is True


class TestConfigLoadable:
    """Test that generated configs can be loaded by SimpleConfig."""

    def test_http_simple_load_and_validate_structure(self) -> None:
        cfg = create_http_simple(port=9090, log_dir="./logs")
        with tempfile.NamedTemporaryFile(suffix=".json", delete=False, mode="w") as f:
            f.write(json.dumps(cfg, indent=2))
            path = f.name
        try:
            from mcp_proxy_adapter.core.config.simple_config import SimpleConfig

            simple = SimpleConfig(path)
            model = simple.load()
            assert model.server.port == 9090
            assert model.server.protocol == "http"
            assert model.server.servername
        finally:
            Path(path).unlink(missing_ok=True)


def run_comprehensive_tests() -> bool:
    """Run all test methods and return True if all passed."""
    print("🧪 Running config_factory tests")
    print("=" * 60)
    total = 0
    passed = 0
    failed = []
    for cls in (TestConfigFactory, TestConfigLoadable):
        print(f"\n📋 {cls.__name__}")
        print("-" * 40)
        inst = cls()
        for name in dir(inst):
            if name.startswith("test_") and callable(getattr(inst, name)):
                total += 1
                try:
                    getattr(inst, name)()
                    print(f"  ✅ {name}")
                    passed += 1
                except Exception as e:
                    print(f"  ❌ {name}: {e}")
                    failed.append(f"{cls.__name__}.{name}: {e}")
    print(f"\n{'=' * 60}")
    print(f"Total: {total}, Passed: {passed}, Failed: {len(failed)}")
    if failed:
        for f in failed:
            print(f"  • {f}")
        return False
    print("🎉 All tests passed!")
    return True


if __name__ == "__main__":
    exit(0 if run_comprehensive_tests() else 1)
