"""Standalone Phase 1 site, key lifecycle, and replay checks."""

from __future__ import annotations

import sys
import unittest
from datetime import datetime, timedelta, timezone
from pathlib import Path


PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT))
loaded_platform = sys.modules.get("platform")
if loaded_platform is not None and not hasattr(loaded_platform, "__path__"):
    del sys.modules["platform"]

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool

from config.db import Base
from platform.sites import registry
from platform.tenants.models import Plan, Tenant


def public_key_pem() -> str:
    key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    return key.public_key().public_bytes(
        Encoding.PEM,
        PublicFormat.SubjectPublicKeyInfo,
    ).decode("utf-8")


class SiteRegistryChecks(unittest.TestCase):
    def setUp(self):
        self.engine = create_engine(
            "sqlite://",
            connect_args={"check_same_thread": False},
            poolclass=StaticPool,
            future=True,
        )
        Base.metadata.create_all(self.engine)
        self.original_session_factory = registry.get_control_plane_session
        registry.get_control_plane_session = lambda: Session(self.engine, future=True)
        with Session(self.engine, future=True) as session:
            session.add(Plan(plan_id="test", code="test", name="Test"))
            session.add(
                Tenant(
                    tenant_id="tenant-a",
                    slug="tenant-a",
                    name="Tenant A",
                    status="active",
                    is_active=True,
                    plan_id="test",
                )
            )
            session.commit()

    def tearDown(self):
        registry.get_control_plane_session = self.original_session_factory
        self.engine.dispose()

    def register(self):
        registry.register_bootstrap_site(
            site_id="site-a",
            tenant_id="tenant-a",
            issuer="https://example.test",
            audience="absolutems-api",
            key_id="key-1",
            public_key_pem=public_key_pem(),
        )

    def test_bootstrap_registration_and_lookup(self):
        self.register()
        key = registry.get_active_signing_key("key-1")
        self.assertEqual("site-a", key["site_id"])
        self.assertEqual("tenant-a", key["tenant_id"])

    def test_replayed_jti_is_rejected(self):
        self.register()
        expiry = datetime.now(timezone.utc) + timedelta(minutes=5)
        registry.consume_jti(site_id="site-a", jti="same-token", expires_at=expiry)
        with self.assertRaisesRegex(PermissionError, "replay"):
            registry.consume_jti(site_id="site-a", jti="same-token", expires_at=expiry)

    def test_rotation_and_revocation(self):
        self.register()
        registry.rotate_signing_key(
            site_id="site-a",
            current_key_id="key-1",
            new_key_id="key-2",
            public_key_pem=public_key_pem(),
        )
        self.assertIsNotNone(registry.get_active_signing_key("key-1"))
        self.assertIsNotNone(registry.get_active_signing_key("key-2"))
        registry.revoke_signing_key(
            site_id="site-a",
            key_id="key-1",
            current_key_id="key-2",
        )
        self.assertIsNone(registry.get_active_signing_key("key-1"))


if __name__ == "__main__":
    unittest.main(verbosity=2)
