"""
Trustmark Badge System - Day 7 Hardening Sprint

Annotates receipts with integrity tier badges based on cryptographic proofs.

Integrity Tiers (ascending strength):
1. HASH - Basic JCS canonical hash (RFC 8785)
2. SIGNED - Ed25519 digital signature
3. TIMESTAMPED - RFC 3161 TSA timestamp token
4. TRANSPARENT - Rekor transparency log inclusion
5. QUANTUM_RESISTANT - Hybrid Ed25519 + ML-DSA signatures

Reference: COPILOT_HARDENING_EPIC.md (Day 7), tools/verify/docs/ROADMAP_STATUS.md
"""

from typing import Dict, Any, Optional, Literal
from dataclasses import dataclass
from datetime import datetime, timezone
import logging

logger = logging.getLogger(__name__)

# Integrity tier definitions
TrustLevel = Literal["hash", "signed", "timestamped", "transparent", "quantum_resistant"]

TIER_HIERARCHY = ["hash", "signed", "timestamped", "transparent", "quantum_resistant"]

TIER_DISPLAY_NAMES = {
    "hash": "Hash Only",
    "signed": "Digitally Signed",
    "timestamped": "Timestamped",
    "transparent": "Transparency Log",
    "quantum_resistant": "Quantum-Resistant"
}

TIER_DESCRIPTIONS = {
    "hash": "Cryptographic hash for integrity verification",
    "signed": "Ed25519 digital signature for authenticity",
    "timestamped": "RFC 3161 timestamp from trusted TSA",
    "transparent": "Rekor transparency log for public auditability",
    "quantum_resistant": "Hybrid post-quantum signature (Ed25519 + ML-DSA)"
}

TIER_EMOJI = {
    "hash": "🔒",
    "signed": "✍️",
    "timestamped": "⏰",
    "transparent": "🌐",
    "quantum_resistant": "🛡️"
}


@dataclass
class TrustmarkBadge:
    """
    Trustmark badge indicating receipt integrity level.

    Attributes:
        level: Integrity tier (hash, signed, timestamped, transparent, quantum_resistant)
        display_name: Human-readable tier name
        description: Tier description
        emoji: Visual indicator
        computed_at: When badge was computed
        proofs_present: Dict of which proofs are present
        degraded: Whether this is a degraded state (expected higher tier)
        degradation_reason: Why tier was downgraded (if applicable)
    """
    level: TrustLevel
    display_name: str
    description: str
    emoji: str
    computed_at: datetime
    proofs_present: Dict[str, bool]
    degraded: bool = False
    degradation_reason: Optional[str] = None

    def to_dict(self) -> Dict[str, Any]:
        """Serialize to dict for receipt embedding."""
        return {
            "level": self.level,
            "display_name": self.display_name,
            "description": self.description,
            "emoji": self.emoji,
            "computed_at": self.computed_at.isoformat(),
            "proofs_present": self.proofs_present,
            "degraded": self.degraded,
            "degradation_reason": self.degradation_reason
        }


def compute_trustmark(
    receipt: Dict[str, Any],
    expected_level: Optional[TrustLevel] = None
) -> TrustmarkBadge:
    """
    Compute trustmark badge from receipt proofs.

    Args:
        receipt: Receipt dict with proof_refs, signature, pq_signature fields
        expected_level: Expected tier (for degradation detection)

    Returns:
        TrustmarkBadge with computed integrity level

    Examples:
        >>> receipt = {"proof_refs": {"jcs_hash": "sha256:..."}, "signature": "ed25519:..."}
        >>> badge = compute_trustmark(receipt)
        >>> badge.level
        'signed'
    """
    proofs_present = _detect_proofs(receipt)
    effective_level = _compute_effective_level(proofs_present)

    # Detect degradation
    degraded = False
    degradation_reason = None
    if expected_level and TIER_HIERARCHY.index(effective_level) < TIER_HIERARCHY.index(expected_level):
        degraded = True
        degradation_reason = f"Expected {expected_level}, achieved {effective_level}"
        logger.warning(f"Trustmark degraded: {degradation_reason}")

    return TrustmarkBadge(
        level=effective_level,
        display_name=TIER_DISPLAY_NAMES[effective_level],
        description=TIER_DESCRIPTIONS[effective_level],
        emoji=TIER_EMOJI[effective_level],
        computed_at=datetime.now(timezone.utc),
        proofs_present=proofs_present,
        degraded=degraded,
        degradation_reason=degradation_reason
    )


def _detect_proofs(receipt: Dict[str, Any]) -> Dict[str, bool]:
    """
    Detect which cryptographic proofs are present in receipt.

    Args:
        receipt: Receipt dict

    Returns:
        Dict mapping proof type to presence boolean
    """
    proof_refs = receipt.get("proof_refs", {})

    return {
        "jcs_hash": bool(proof_refs.get("jcs_hash")),
        "signature": bool(receipt.get("signature")),
        "pq_signature": bool(receipt.get("pq_signature")),
        "tsa_timestamp": bool(proof_refs.get("tsa_ref")),
        "rekor_inclusion": bool(proof_refs.get("rekor_uuid")),
        "batch_merkle": bool(proof_refs.get("batch_id"))
    }


def _compute_effective_level(proofs: Dict[str, bool]) -> TrustLevel:
    """
    Compute effective integrity level from proof presence.

    Rules (highest tier wins):
    1. quantum_resistant: Ed25519 + ML-DSA signatures present
    2. transparent: Rekor inclusion proof present
    3. timestamped: TSA timestamp present
    4. signed: Ed25519 signature present
    5. hash: JCS hash present (baseline)

    Args:
        proofs: Dict of proof presence flags

    Returns:
        Effective integrity tier
    """
    # Tier 5: Quantum-resistant (both signatures)
    if proofs["signature"] and proofs["pq_signature"]:
        return "quantum_resistant"

    # Tier 4: Transparent (Rekor inclusion)
    if proofs["rekor_inclusion"]:
        return "transparent"

    # Tier 3: Timestamped (TSA)
    if proofs["tsa_timestamp"]:
        return "timestamped"

    # Tier 2: Signed (Ed25519)
    if proofs["signature"]:
        return "signed"

    # Tier 1: Hash (baseline)
    if proofs["jcs_hash"]:
        return "hash"

    # Fallback (should never happen if receipt is valid)
    logger.warning("No proofs detected in receipt - defaulting to 'hash' level")
    return "hash"


def format_trustmark_badge(badge: TrustmarkBadge, format: str = "text") -> str:
    """
    Format trustmark badge for display.

    Args:
        badge: TrustmarkBadge instance
        format: Output format ("text", "emoji", "full")

    Returns:
        Formatted badge string

    Examples:
        >>> badge = TrustmarkBadge(level="signed", ...)
        >>> format_trustmark_badge(badge, format="emoji")
        '✍️ Digitally Signed'
        >>> format_trustmark_badge(badge, format="full")
        '✍️ Digitally Signed (Ed25519 digital signature for authenticity)'
    """
    if format == "emoji":
        return f"{badge.emoji} {badge.display_name}"
    elif format == "full":
        base = f"{badge.emoji} {badge.display_name} ({badge.description})"
        if badge.degraded:
            base += f" [DEGRADED: {badge.degradation_reason}]"
        return base
    else:  # text
        return badge.display_name


def upgrade_path_available(current_level: TrustLevel) -> Optional[TrustLevel]:
    """
    Determine next available upgrade tier.

    Args:
        current_level: Current integrity tier

    Returns:
        Next tier in hierarchy, or None if at max

    Examples:
        >>> upgrade_path_available("signed")
        'timestamped'
        >>> upgrade_path_available("quantum_resistant")
        None
    """
    current_idx = TIER_HIERARCHY.index(current_level)
    if current_idx < len(TIER_HIERARCHY) - 1:
        return TIER_HIERARCHY[current_idx + 1]
    return None


def validate_trustmark_consistency(receipt: Dict[str, Any]) -> list[str]:
    """
    Validate that trustmark matches actual proofs in receipt.

    Args:
        receipt: Receipt dict with trustmark and proof fields

    Returns:
        List of validation warnings (empty if consistent)

    Examples:
        >>> warnings = validate_trustmark_consistency(receipt)
        >>> if warnings:
        ...     print(f"Inconsistencies: {warnings}")
    """
    warnings = []

    # Check if trustmark exists
    trustmark = receipt.get("trustmark")
    if not trustmark:
        warnings.append("No trustmark present in receipt")
        return warnings

    # Recompute badge and compare
    computed_badge = compute_trustmark(receipt)
    stored_level = trustmark.get("level")

    if stored_level != computed_badge.level:
        warnings.append(
            f"Trustmark mismatch: stored={stored_level}, computed={computed_badge.level}"
        )

    # Check proof_level field consistency (if present)
    proof_refs = receipt.get("proof_refs", {})
    proof_level = proof_refs.get("proof_level")
    if proof_level and proof_level != stored_level:
        warnings.append(
            f"proof_refs.proof_level ({proof_level}) inconsistent with trustmark.level ({stored_level})"
        )

    return warnings


def recommend_upgrades(badge: TrustmarkBadge) -> list[Dict[str, str]]:
    """
    Recommend trustmark upgrade actions.

    Args:
        badge: Current trustmark badge

    Returns:
        List of upgrade recommendations with actions

    Examples:
        >>> badge = TrustmarkBadge(level="signed", ...)
        >>> recommendations = recommend_upgrades(badge)
        >>> for rec in recommendations:
        ...     print(f"{rec['tier']}: {rec['action']}")
    """
    recommendations = []
    current_idx = TIER_HIERARCHY.index(badge.level)

    # Recommend each higher tier
    for tier in TIER_HIERARCHY[current_idx + 1:]:
        action = None

        if tier == "timestamped":
            action = "Add RFC 3161 TSA timestamp via tools/crypto/rfc3161_client.py"
        elif tier == "transparent":
            action = "Submit to Rekor transparency log via tools/crypto/rekor_client.py"
        elif tier == "quantum_resistant":
            action = "Add ML-DSA signature alongside Ed25519 (hybrid mode)"

        if action:
            recommendations.append({
                "tier": tier,
                "display_name": TIER_DISPLAY_NAMES[tier],
                "action": action
            })

    return recommendations


# CLI utility functions

def print_badge_summary(badge: TrustmarkBadge) -> None:
    """Print human-readable badge summary to console."""
    print("\n" + "=" * 60)
    print(f"  TRUSTMARK BADGE: {format_trustmark_badge(badge, format='emoji')}")
    print("=" * 60)
    print(f"  Level: {badge.level}")
    print(f"  Description: {badge.description}")
    print(f"  Computed: {badge.computed_at.isoformat()}")

    if badge.degraded:
        print(f"  ⚠️  DEGRADED: {badge.degradation_reason}")

    print("\n  Proofs Present:")
    for proof_type, present in badge.proofs_present.items():
        status = "✅" if present else "❌"
        print(f"    {status} {proof_type}")

    # Upgrade recommendations
    recommendations = recommend_upgrades(badge)
    if recommendations:
        print("\n  📈 Upgrade Recommendations:")
        for rec in recommendations:
            print(f"    • {rec['display_name']}: {rec['action']}")
    else:
        print("\n  🏆 Maximum integrity tier achieved!")

    print("=" * 60 + "\n")


# =============================================================================
# BACKWARDS COMPATIBILITY ALIAS
# =============================================================================

def generate_trustmark(
    receipt: Dict[str, Any],
    version: Optional[str] = None,
    expected_level: Optional[TrustLevel] = None
) -> TrustmarkBadge:
    """
    Backwards-compatible alias for compute_trustmark.

    Args:
        receipt: Receipt dict with proof_refs, signature, pq_signature fields
        version: Ignored (kept for API compatibility with writer.py)
        expected_level: Expected tier (for degradation detection)

    Returns:
        TrustmarkBadge with computed integrity level
    """
    return compute_trustmark(receipt, expected_level=expected_level)


# CLI entry point
if __name__ == "__main__":
    import argparse
    import json
    import sys

    parser = argparse.ArgumentParser(description="Compute trustmark badge for receipt")
    parser.add_argument("receipt_file", help="Path to receipt JSON file")
    parser.add_argument("--format", choices=["text", "emoji", "full", "json"], default="full")
    parser.add_argument("--validate", action="store_true", help="Validate trustmark consistency")

    args = parser.parse_args()

    try:
        with open(args.receipt_file, 'r') as f:
            receipt = json.load(f)

        badge = compute_trustmark(receipt)

        if args.format == "json":
            print(json.dumps(badge.to_dict(), indent=2))
        else:
            print_badge_summary(badge)

        if args.validate:
            warnings = validate_trustmark_consistency(receipt)
            if warnings:
                print("\n⚠️  VALIDATION WARNINGS:")
                for warning in warnings:
                    print(f"  • {warning}")
                sys.exit(1)

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)
