import os
import unittest
from unittest.mock import patch

os.environ.setdefault("DATABASE_URL", "mysql+pymysql://test:test@127.0.0.1/documenta")
os.environ.setdefault("REDIS_URL", "redis://127.0.0.1:6379/0")
os.environ.setdefault("APP_ENCRYPTION_KEY", "dGVzdC1rZXktZm9yLWRvY3VtZW50YS0zMmJ5dGVzISE=")
os.environ.setdefault("PII_HMAC_KEY", "test-pii-key")
os.environ.setdefault("ACCESS_TOKEN_HMAC_KEY", "test-access-key")

from pydantic import ValidationError

from app.api.verification_routes import RepositoryIn
from app.main import app
from app.services.document_service import document_verification_code
from app.services.verification_service import _json_path, mask_code, normalize_verification_code


class H11VerificationContractTests(unittest.TestCase):
    def test_routes_are_registered(self):
        paths = {route.path for route in app.routes}
        expected = {
            "/api/v1/portal/verificacion/consultar",
            "/api/v1/portal/verificacion/estado",
            "/api/v1/panel/admin/verificacion",
            "/api/v1/panel/admin/verificacion/repositories",
            "/api/v1/panel/admin/verificacion/repositories/{repository_id}",
            "/api/v1/panel/admin/verificacion/repositories/{repository_id}/credentials",
            "/api/v1/panel/admin/verificacion/repositories/{repository_id}/test",
            "/api/v1/panel/admin/verificacion/checks/{verification_uuid}",
        }
        self.assertTrue(expected.issubset(paths), expected - paths)

    def test_codes_are_normalized_and_stable(self):
        self.assertEqual(normalize_verification_code(" doc-abc-123 "), "DOC-ABC-123")
        self.assertEqual(document_verification_code("DOC123", "pdf"), "DOC-DOC123-PDF")
        self.assertEqual(mask_code("DOC-ABCDEFGH-1234"), "DOC-AB…1234")
        with self.assertRaises(ValueError):
            normalize_verification_code("<script>")

    def test_internal_repository_does_not_accept_external_secret_contract(self):
        repository = RepositoryIn(
            codigo="DOCUMENTA", nombre="Documenta", tipo_conector="INTERNO_DOCUMENTA",
            endpoint_base="https://example.com", auth_tipo="BEARER",
        )
        self.assertIsNone(repository.endpoint_base)
        self.assertEqual(repository.auth_tipo, "NINGUNA")

    def test_http_repository_requires_explicit_mapping_and_public_https(self):
        with self.assertRaises(ValidationError):
            RepositoryIn(codigo="LOCAL", nombre="Local", tipo_conector="HTTP_JSON",
                         endpoint_base="http://127.0.0.1/verify", status_path="data.status")
        with patch("app.services.verification_service.socket.getaddrinfo",
                   return_value=[(2, 1, 6, "", ("93.184.216.34", 443))]):
            with self.assertRaises(ValidationError):
                RepositoryIn(codigo="EXTERNO", nombre="Externo", tipo_conector="HTTP_JSON",
                             endpoint_base="https://example.com/verify")
            valid = RepositoryIn(codigo="EXTERNO", nombre="Externo", tipo_conector="HTTP_JSON",
                                 endpoint_base="https://example.com/verify", status_path="data.status")
            self.assertEqual(valid.endpoint_base, "https://example.com/verify")

    def test_json_mapping_is_bounded_and_deterministic(self):
        payload = {"data": {"documents": [{"status": "VALIDO"}]}}
        self.assertEqual(_json_path(payload, "data.documents.0.status"), "VALIDO")
        self.assertIsNone(_json_path(payload, "data.documents.2.status"))


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