"""AgenLang Contract - loads and validates the v1.0 schema with cryptographic verification."""

import json
from pathlib import Path
from pydantic import BaseModel, Field
from jsonschema import validate, ValidationError
from typing import Dict, Any, Optional, Literal
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.exceptions import InvalidSignature

SCHEMA_PATH = Path(__file__).parent.parent.parent / "schema" / "v1.0.json"

class Contract(BaseModel):
    """AgenLang v1.0 Contract - the core object agents exchange."""

    agenlang_version: Literal["1.0"] = "1.0"
    contract_id: str
    issuer: Dict[str, Any]
    goal: str
    intent_anchor: Dict[str, Any]
    constraints: Dict[str, Any]
    workflow: Dict[str, Any]
    memory_contract: Dict[str, Any]
    settlement: Dict[str, Any]
    capability_attestations: list
    ser_config: Dict[str, Any]
    ser: Optional[Dict[str, Any]] = None

    @classmethod
    def from_file(cls, path: str) -> "Contract":
        """Load a contract from JSON file and validate against schema."""
        data = json.loads(Path(path).read_text())
        return cls.from_dict(data)

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "Contract":
        """Load from dict and validate."""
        with open(SCHEMA_PATH) as f:
            schema = json.load(f)
        try:
            validate(instance=data, schema=schema)
        except ValidationError as e:
            raise ValueError(f"Invalid AgenLang contract: {e.message}") from e

        contract = cls(**data)
        contract._verify_issuer_signature()
        return contract

    def _verify_issuer_signature(self):
        """Verify the issuer's proof signature (ed25519)."""
        pubkey_hex = self.issuer.get("pubkey")
        proof = self.issuer.get("proof")
        if not pubkey_hex or not proof:
            return  # Proof is optional in v1.0 for testing

        try:
            pubkey_bytes = bytes.fromhex(pubkey_hex)
            pubkey = Ed25519PublicKey.from_public_bytes(pubkey_bytes)
            signature = bytes.fromhex(proof)
            pubkey.verify(signature, self.contract_id.encode('utf-8'))
            print(f"✅ Issuer signature verified for {self.issuer['agent_id']}")
        except (ValueError, InvalidSignature):
            raise ValueError("❌ Invalid issuer signature - contract may be forged")

    def to_json(self) -> str:
        """Export as JSON string."""
        return self.model_dump_json(indent=2)
