#!/usr/bin/env python3
"""FIDO2 Passwordless Auth Agent - audits FIDO2 deployment readiness and credential status."""

import json
import argparse
import logging
import subprocess
from datetime import datetime

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)


def graph_api(token, endpoint):
    cmd = ["curl", "-s", "-H", f"Authorization: Bearer {token}",
           f"https://graph.microsoft.com/v1.0{endpoint}"]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
    return json.loads(result.stdout) if result.stdout else {}


def get_fido2_policy(token):
    return graph_api(token, "/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/fido2")


def get_registrations(token):
    return graph_api(token, "/reports/authenticationMethods/userRegistrationDetails")


def audit_fido2_policy(policy):
    findings = []
    if policy.get("state") != "enabled":
        findings.append({"issue": f"FIDO2 policy state: {policy.get('state', 'unknown')}", "severity": "high"})
    if not policy.get("keyRestrictions", {}).get("aaGuids"):
        findings.append({"issue": "No AAGUID restrictions set", "severity": "medium"})
    if not policy.get("isAttestationEnforced"):
        findings.append({"issue": "Attestation not enforced", "severity": "medium"})
    return findings


def analyze_adoption(registrations):
    users = registrations.get("value", [])
    total = len(users)
    fido2 = sum(1 for u in users if "fido2" in str(u.get("methodsRegistered", [])).lower())
    passwordless = sum(1 for u in users if u.get("isPasswordlessCapable", False))
    return {
        "total_users": total, "fido2_registered": fido2, "passwordless_capable": passwordless,
        "fido2_adoption_rate": round(fido2 / max(total, 1) * 100, 1),
    }


def check_rp_config(rp_url):
    cmd = ["curl", "-s", f"{rp_url}/.well-known/webauthn"]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
    findings = []
    try:
        config = json.loads(result.stdout)
    except json.JSONDecodeError:
        config = {}
        findings.append({"issue": "WebAuthn well-known not configured", "severity": "high"})
    return {"config": config, "findings": findings}


def generate_report(policy, policy_findings, adoption, rp):
    return {
        "timestamp": datetime.utcnow().isoformat(),
        "fido2_policy_state": policy.get("state", "unknown"),
        "policy_findings": policy_findings, "adoption_metrics": adoption,
        "rp_config": rp,
        "total_findings": len(policy_findings) + len(rp.get("findings", [])),
    }


def main():
    parser = argparse.ArgumentParser(description="FIDO2 Passwordless Authentication Audit Agent")
    parser.add_argument("--token", required=True, help="Graph API bearer token")
    parser.add_argument("--rp-url", help="WebAuthn relying party URL")
    parser.add_argument("--output", default="fido2_audit_report.json")
    args = parser.parse_args()
    policy = get_fido2_policy(args.token)
    policy_findings = audit_fido2_policy(policy)
    registrations = get_registrations(args.token)
    adoption = analyze_adoption(registrations)
    rp = check_rp_config(args.rp_url) if args.rp_url else {"config": {}, "findings": []}
    report = generate_report(policy, policy_findings, adoption, rp)
    with open(args.output, "w") as f:
        json.dump(report, f, indent=2, default=str)
    logger.info("FIDO2: adoption %.1f%%, %d findings", adoption["fido2_adoption_rate"], report["total_findings"])
    print(json.dumps(report, indent=2, default=str))

if __name__ == "__main__":
    main()
