"""ACM Ethics Mapping - traceable to evidence, no scoring."""
from typing import Dict, Any, List, Optional


# ACM Code of Ethics Principles relevant to AI systems
ACM_PRINCIPLES = {
    "1.1": {
        "name": "Contribute to society and human well-being",
        "description": "AI systems should benefit society and respect human dignity"
    },
    "1.2": {
        "name": "Avoid harm",
        "description": "AI systems should minimize harm to individuals and groups"
    },
    "2.3": {
        "name": "Know and respect existing rules",
        "description": "Comply with laws, regulations, and professional standards"
    },
    "2.5": {
        "name": "Give proper credit for intellectual property",
        "description": "Respect intellectual property rights"
    },
    "3.1": {
        "name": "Ensure that the public good is the central concern",
        "description": "Prioritize public welfare in system design"
    },
    "3.2": {
        "name": "Articulate, support, and update full knowledge of the work",
        "description": "Maintain transparency and documentation"
    },
    "3.3": {
        "name": "Maintain high standards of professional competence",
        "description": "Apply professional standards to AI systems"
    },
    "3.4": {
        "name": "Know and respect existing rules pertaining to professional work",
        "description": "Follow applicable regulations and standards"
    },
    "3.5": {
        "name": "Accept and provide appropriate professional review",
        "description": "Support auditability and review processes"
    }
}


def map_ethics_to_evidence(
    metrics: Dict[str, Any],
    thresholds: Dict[str, float],
    governance_checks: Dict[str, Any],
    has_evidence_storage: bool = False
) -> Dict[str, Any]:
    """
    Map ACM ethics principles to existing evidence.
    Returns traceable mappings - no scores or moral judgments.
    """
    mappings = {}
    
    # Principle 1.2: Avoid harm - supported by fairness metrics
    principle_1_2 = {
        "principle_id": "1.2",
        "principle_name": ACM_PRINCIPLES["1.2"]["name"],
        "evidence_present": [],
        "gaps": []
    }
    
    if metrics:
        # Demographic parity supports avoiding disparate treatment
        if any("demographic_parity" in k for k in metrics.keys()):
            principle_1_2["evidence_present"].append({
                "type": "metric",
                "name": "Demographic Parity Difference",
                "description": "Measures whether model treats different groups equally in approval rates"
            })
        else:
            principle_1_2["gaps"].append("Demographic parity metrics not calculated")
        
        # Equal opportunity supports avoiding discrimination
        if any("equal_opportunity" in k for k in metrics.keys()):
            principle_1_2["evidence_present"].append({
                "type": "metric",
                "name": "Equal Opportunity Difference",
                "description": "Measures whether model has equal accuracy for positive outcomes across groups"
            })
        else:
            principle_1_2["gaps"].append("Equal opportunity metrics not calculated")
        
        # Disparate impact supports avoiding disproportionate effects
        if any("disparate_impact" in k or "ratio" in k for k in metrics.keys()):
            principle_1_2["evidence_present"].append({
                "type": "metric",
                "name": "Disparate Impact Ratio",
                "description": "Measures relative fairness across protected groups"
            })
        else:
            principle_1_2["gaps"].append("Disparate impact metrics not calculated")
    
    mappings["1.2"] = principle_1_2
    
    # Principle 2.3: Know and respect existing rules - supported by governance
    principle_2_3 = {
        "principle_id": "2.3",
        "principle_name": ACM_PRINCIPLES["2.3"]["name"],
        "evidence_present": [],
        "gaps": []
    }
    
    if governance_checks and governance_checks.get("checks"):
        checks = governance_checks["checks"]
        if checks.get("sensitive_attributes_declared"):
            principle_2_3["evidence_present"].append({
                "type": "governance",
                "name": "Sensitive Attributes Declared",
                "description": "Protected attributes are explicitly identified"
            })
        else:
            principle_2_3["gaps"].append("Sensitive attributes not explicitly declared")
        
        if checks.get("thresholds_explicit"):
            principle_2_3["evidence_present"].append({
                "type": "governance",
                "name": "Explicit Thresholds",
                "description": "Fairness thresholds are explicitly defined"
            })
        else:
            principle_2_3["gaps"].append("Fairness thresholds not explicitly defined")
    
    mappings["2.3"] = principle_2_3
    
    # Principle 3.2: Articulate and support knowledge - supported by evidence storage
    principle_3_2 = {
        "principle_id": "3.2",
        "principle_name": ACM_PRINCIPLES["3.2"]["name"],
        "evidence_present": [],
        "gaps": []
    }
    
    if has_evidence_storage:
        principle_3_2["evidence_present"].append({
            "type": "governance",
            "name": "Evidence Storage",
            "description": "Audit evidence is stored immutably for review"
        })
    else:
        principle_3_2["gaps"].append("Evidence storage not enabled")
    
    if thresholds:
        principle_3_2["evidence_present"].append({
            "type": "governance",
            "name": "Threshold Documentation",
            "description": "Fairness thresholds are documented and enforced"
        })
    
    mappings["3.2"] = principle_3_2
    
    # Principle 3.5: Accept professional review - supported by auditability
    principle_3_5 = {
        "principle_id": "3.5",
        "principle_name": ACM_PRINCIPLES["3.5"]["name"],
        "evidence_present": [],
        "gaps": []
    }
    
    if has_evidence_storage:
        principle_3_5["evidence_present"].append({
            "type": "governance",
            "name": "Audit Trail",
            "description": "Complete audit history is maintained for review"
        })
    else:
        principle_3_5["gaps"].append("Audit trail not maintained")
    
    if metrics:
        principle_3_5["evidence_present"].append({
            "type": "metric",
            "name": "Traceable Metrics",
            "description": "All fairness metrics are calculated and traceable to system behavior"
        })
    
    mappings["3.5"] = principle_3_5
    
    return {
        "mappings": mappings,
        "summary": {
            "total_principles_mapped": len(mappings),
            "principles_with_evidence": sum(1 for m in mappings.values() if len(m["evidence_present"]) > 0),
            "principles_with_gaps": sum(1 for m in mappings.values() if len(m["gaps"]) > 0)
        }
    }

