#!/usr/bin/env python3
"""AWS GuardDuty findings automation and detection agent."""

import json
import sys
import argparse
from datetime import datetime

try:
    import boto3
except ImportError:
    print("Install: pip install boto3")
    sys.exit(1)


def get_guardduty_detector(session):
    """Get the active GuardDuty detector ID."""
    gd = session.client("guardduty")
    detectors = gd.list_detectors()["DetectorIds"]
    if not detectors:
        return None
    return detectors[0]


def list_findings(session, detector_id, severity_min=4.0, max_results=50):
    """List GuardDuty findings filtered by severity."""
    gd = session.client("guardduty")
    criteria = {
        "Criterion": {
            "severity": {"Gte": severity_min},
            "service.archived": {"Eq": ["false"]},
        }
    }
    finding_ids = gd.list_findings(
        DetectorId=detector_id,
        FindingCriteria=criteria,
        SortCriteria={"AttributeName": "severity", "OrderBy": "DESC"},
        MaxResults=max_results,
    )["FindingIds"]

    if not finding_ids:
        return []

    details = gd.get_findings(
        DetectorId=detector_id, FindingIds=finding_ids
    )["Findings"]

    results = []
    for f in details:
        results.append({
            "id": f.get("Id", ""),
            "type": f.get("Type", ""),
            "severity": f.get("Severity", 0),
            "title": f.get("Title", ""),
            "description": f.get("Description", "")[:200],
            "resource_type": f.get("Resource", {}).get("ResourceType", ""),
            "region": f.get("Region", ""),
            "first_seen": f.get("Service", {}).get("EventFirstSeen", ""),
            "last_seen": f.get("Service", {}).get("EventLastSeen", ""),
            "count": f.get("Service", {}).get("Count", 0),
            "action_type": f.get("Service", {}).get("Action", {}).get("ActionType", ""),
        })
    return results


def get_finding_statistics(session, detector_id):
    """Get finding count grouped by type and severity."""
    gd = session.client("guardduty")
    stats = gd.get_findings_statistics(
        DetectorId=detector_id,
        FindingStatisticTypes=["COUNT_BY_SEVERITY"],
    )
    return stats.get("FindingStatistics", {})


def check_detector_configuration(session, detector_id):
    """Audit GuardDuty detector configuration for coverage gaps."""
    gd = session.client("guardduty")
    findings = []

    detector = gd.get_detector(DetectorId=detector_id)
    status = detector.get("Status", "")
    if status != "ENABLED":
        findings.append({
            "check": "Detector status",
            "status": status,
            "severity": "CRITICAL",
            "issue": "GuardDuty detector is not enabled",
        })

    features = detector.get("Features", [])
    expected_features = {
        "S3_DATA_EVENTS", "EKS_AUDIT_LOGS", "EBS_MALWARE_PROTECTION",
        "RDS_LOGIN_EVENTS", "LAMBDA_NETWORK_LOGS", "RUNTIME_MONITORING",
    }
    enabled_features = set()
    for feat in features:
        if feat.get("Status") == "ENABLED":
            enabled_features.add(feat.get("Name", ""))

    missing = expected_features - enabled_features
    for m in missing:
        findings.append({
            "check": f"Feature: {m}",
            "status": "DISABLED",
            "severity": "HIGH",
            "issue": f"GuardDuty feature {m} not enabled — reduced detection coverage",
        })

    return findings


def check_member_accounts(session, detector_id):
    """Check GuardDuty member account enrollment in multi-account setup."""
    gd = session.client("guardduty")
    members = gd.list_members(
        DetectorId=detector_id, OnlyAssociated="true"
    ).get("Members", [])

    results = []
    for m in members:
        status = m.get("RelationshipStatus", "")
        results.append({
            "account_id": m.get("AccountId", ""),
            "email": m.get("Email", ""),
            "status": status,
            "detector_id": m.get("DetectorId", ""),
        })
        if status != "Enabled":
            results[-1]["finding"] = f"Member account not fully enabled: {status}"
            results[-1]["severity"] = "HIGH"
    return results


def auto_archive_low_severity(session, detector_id, threshold=2.0):
    """Auto-archive findings below severity threshold."""
    gd = session.client("guardduty")
    criteria = {
        "Criterion": {
            "severity": {"Lt": threshold},
            "service.archived": {"Eq": ["false"]},
        }
    }
    finding_ids = gd.list_findings(
        DetectorId=detector_id,
        FindingCriteria=criteria,
        MaxResults=100,
    )["FindingIds"]

    if finding_ids:
        gd.archive_findings(DetectorId=detector_id, FindingIds=finding_ids)
    return {"archived_count": len(finding_ids)}


def run_audit(args):
    """Execute GuardDuty findings automation audit."""
    print(f"\n{'='*60}")
    print(f"  AWS GUARDDUTY FINDINGS AUTOMATION")
    print(f"  Generated: {datetime.utcnow().isoformat()} UTC")
    print(f"{'='*60}\n")

    session = boto3.Session(profile_name=args.profile, region_name=args.region)
    report = {}

    detector_id = get_guardduty_detector(session)
    if not detector_id:
        print("ERROR: No GuardDuty detector found")
        return {"error": "No detector found"}

    report["detector_id"] = detector_id
    print(f"Detector ID: {detector_id}\n")

    config_findings = check_detector_configuration(session, detector_id)
    report["configuration_findings"] = config_findings
    print(f"--- CONFIGURATION AUDIT ({len(config_findings)} findings) ---")
    for f in config_findings:
        print(f"  [{f['severity']}] {f['check']}: {f['issue']}")

    findings = list_findings(session, detector_id, args.min_severity)
    report["active_findings"] = len(findings)
    print(f"\n--- ACTIVE FINDINGS ({len(findings)}, severity >= {args.min_severity}) ---")
    for f in findings[:15]:
        print(f"  [{f['severity']:.1f}] {f['type']}")
        print(f"         {f['title'][:80]}")

    members = check_member_accounts(session, detector_id)
    report["member_accounts"] = members
    print(f"\n--- MEMBER ACCOUNTS ({len(members)}) ---")
    for m in members:
        status_icon = "OK" if m["status"] == "Enabled" else "WARN"
        print(f"  [{status_icon}] {m['account_id']}: {m['status']}")

    return report


def main():
    parser = argparse.ArgumentParser(description="GuardDuty Findings Automation Agent")
    parser.add_argument("--profile", default=None, help="AWS profile name")
    parser.add_argument("--region", default="us-east-1", help="AWS region")
    parser.add_argument("--min-severity", type=float, default=4.0,
                        help="Minimum severity threshold (default: 4.0)")
    parser.add_argument("--output", help="Save report to JSON file")
    args = parser.parse_args()

    report = run_audit(args)
    if args.output:
        with open(args.output, "w") as f:
            json.dump(report, f, indent=2, default=str)
        print(f"\n[+] Report saved to {args.output}")


if __name__ == "__main__":
    main()
