"""
Module Loader Receipts - Audit trail for module admission.

These receipts track:
    - Module admission attempts
    - Security scan results
    - Verification outcomes
    - Module status changes
    - Runtime violations

Part of the Module Loader that safely admits
new code into the organism.
"""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Any, Dict, List, Optional

from receipts.base import BaseReceipt


class ModuleAdmissionReceipt(BaseReceipt):
    """
    Emitted when a module goes through the admission pipeline.

    Records the full admission process outcome.
    """

    receipt_type: str = "ModuleAdmissionReceipt"
    domain: str = "organism"
    organ: str = "module_loader"

    # Module
    module_id: str
    module_path: str
    version: str
    author: str

    # Outcome
    admitted: bool
    current_stage: str
    rejection_stage: Optional[str]
    rejection_reasons: List[str]

    # Stages completed
    stages_completed: List[str]

    # Timing
    total_time_ms: float

    def __init__(
        self,
        *,
        module_id: str,
        module_path: str,
        version: str,
        author: str,
        admitted: bool,
        current_stage: str,
        rejection_stage: Optional[str],
        rejection_reasons: List[str],
        stages_completed: List[str],
        total_time_ms: float,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"admission_{module_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            module_id=module_id,
            module_path=module_path,
            version=version,
            author=author,
            admitted=admitted,
            current_stage=current_stage,
            rejection_stage=rejection_stage,
            rejection_reasons=rejection_reasons,
            stages_completed=stages_completed,
            total_time_ms=total_time_ms,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class SecurityScanReceipt(BaseReceipt):
    """
    Emitted when a security scan is performed.

    Records what was detected during scanning.
    """

    receipt_type: str = "SecurityScanReceipt"
    domain: str = "organism"
    organ: str = "module_loader"

    # Module
    module_id: str
    module_path: str

    # Result
    passed: bool
    risk_level: str
    issues: List[str]
    warnings: List[str]

    # Detections
    detected_imports: List[str]
    detected_network: bool
    detected_file_io: bool
    detected_exec: bool

    # Metrics
    lines_of_code: int
    complexity_score: float

    def __init__(
        self,
        *,
        module_id: str,
        module_path: str,
        passed: bool,
        risk_level: str,
        issues: List[str],
        warnings: List[str],
        detected_imports: List[str],
        detected_network: bool,
        detected_file_io: bool,
        detected_exec: bool,
        lines_of_code: int,
        complexity_score: float,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"scan_{module_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            module_id=module_id,
            module_path=module_path,
            passed=passed,
            risk_level=risk_level,
            issues=issues,
            warnings=warnings,
            detected_imports=detected_imports,
            detected_network=detected_network,
            detected_file_io=detected_file_io,
            detected_exec=detected_exec,
            lines_of_code=lines_of_code,
            complexity_score=complexity_score,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class ModuleVerificationReceipt(BaseReceipt):
    """
    Emitted when constitutional verification is performed.

    Records compliance evaluation.
    """

    receipt_type: str = "ModuleVerificationReceipt"
    domain: str = "organism"
    organ: str = "module_loader"

    # Module
    module_id: str

    # Result
    passed: bool
    dignity_score: float
    compliance_score: float

    # Policies
    policies_checked: List[str]
    policies_passed: List[str]
    policies_failed: List[str]

    # Issues
    violations: List[str]
    warnings: List[str]

    def __init__(
        self,
        *,
        module_id: str,
        passed: bool,
        dignity_score: float,
        compliance_score: float,
        policies_checked: List[str],
        policies_passed: List[str],
        policies_failed: List[str],
        violations: List[str],
        warnings: List[str],
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"verify_{module_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            module_id=module_id,
            passed=passed,
            dignity_score=dignity_score,
            compliance_score=compliance_score,
            policies_checked=policies_checked,
            policies_passed=policies_passed,
            policies_failed=policies_failed,
            violations=violations,
            warnings=warnings,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class ModuleStatusChangeReceipt(BaseReceipt):
    """
    Emitted when a module's status changes.

    Records suspension, revocation, etc.
    """

    receipt_type: str = "ModuleStatusChangeReceipt"
    domain: str = "organism"
    organ: str = "module_loader"

    # Module
    module_id: str

    # Status change
    old_status: str
    new_status: str
    reason: str

    # Context
    behavior_score: float
    invocation_count: int
    error_count: int

    def __init__(
        self,
        *,
        module_id: str,
        old_status: str,
        new_status: str,
        reason: str,
        behavior_score: float,
        invocation_count: int,
        error_count: int,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"status_{module_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            module_id=module_id,
            old_status=old_status,
            new_status=new_status,
            reason=reason,
            behavior_score=behavior_score,
            invocation_count=invocation_count,
            error_count=error_count,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class ModuleViolationReceipt(BaseReceipt):
    """
    Emitted when a module violates its contract.

    Records runtime violations.
    """

    receipt_type: str = "ModuleViolationReceipt"
    domain: str = "organism"
    organ: str = "module_loader"

    # Module
    module_id: str

    # Violation
    violation_type: str  # "error", "capability_exceeded", "permission_denied"
    description: str
    severity: str  # "low", "medium", "high", "critical"

    # Context
    invocation_count: int
    error_count: int
    behavior_score_before: float
    behavior_score_after: float

    def __init__(
        self,
        *,
        module_id: str,
        violation_type: str,
        description: str,
        severity: str,
        invocation_count: int,
        error_count: int,
        behavior_score_before: float,
        behavior_score_after: float,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"violation_{module_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            module_id=module_id,
            violation_type=violation_type,
            description=description,
            severity=severity,
            invocation_count=invocation_count,
            error_count=error_count,
            behavior_score_before=behavior_score_before,
            behavior_score_after=behavior_score_after,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


__all__ = [
    "ModuleAdmissionReceipt",
    "SecurityScanReceipt",
    "ModuleVerificationReceipt",
    "ModuleStatusChangeReceipt",
    "ModuleViolationReceipt",
]
