#!/usr/bin/env python3
"""Agent for detecting spearphishing emails using email gateway log analysis."""

import argparse
import email
import json
import os
import re
from datetime import datetime, timezone
from email import policy


EXECUTIVE_TITLES = [
    "ceo", "cfo", "cto", "cio", "coo", "president", "director",
    "vp", "vice president", "managing director", "partner",
]
URGENCY_KEYWORDS = [
    "urgent", "immediate", "asap", "right away", "time sensitive",
    "confidential", "do not share", "wire transfer", "bank account",
    "update payment", "invoice attached", "past due",
]
SUSPICIOUS_EXTENSIONS = {
    ".exe", ".scr", ".bat", ".cmd", ".ps1", ".vbs", ".js",
    ".hta", ".lnk", ".iso", ".img", ".dll", ".msi",
}


def parse_email_headers(eml_path):
    """Extract security-relevant headers from an email."""
    with open(eml_path, "rb") as f:
        msg = email.message_from_binary_file(f, policy=policy.default)
    headers = {
        "from": msg.get("From", ""),
        "to": msg.get("To", ""),
        "subject": msg.get("Subject", ""),
        "reply_to": msg.get("Reply-To", ""),
        "return_path": msg.get("Return-Path", ""),
        "received_spf": msg.get("Received-SPF", ""),
        "dkim_signature": msg.get("DKIM-Signature", ""),
        "authentication_results": msg.get("Authentication-Results", ""),
        "x_mailer": msg.get("X-Mailer", ""),
        "message_id": msg.get("Message-ID", ""),
    }
    return headers, msg


def check_authentication(headers):
    """Verify SPF, DKIM, DMARC authentication results."""
    issues = []
    auth_results = headers.get("authentication_results", "").lower()
    if "spf=fail" in auth_results or "spf=softfail" in auth_results:
        issues.append("SPF validation failed")
    if "dkim=fail" in auth_results:
        issues.append("DKIM validation failed")
    if "dmarc=fail" in auth_results:
        issues.append("DMARC validation failed")
    if not headers.get("dkim_signature"):
        issues.append("No DKIM signature present")
    from_domain = re.search(r"@([\w.-]+)", headers.get("from", ""))
    reply_domain = re.search(r"@([\w.-]+)", headers.get("reply_to", ""))
    if from_domain and reply_domain and from_domain.group(1) != reply_domain.group(1):
        issues.append(f"Reply-To domain mismatch: {reply_domain.group(1)} vs {from_domain.group(1)}")
    return issues


def check_content_indicators(msg):
    """Analyze email body for spearphishing content indicators."""
    indicators = []
    body = ""
    for part in msg.walk():
        if part.get_content_type() in ("text/plain", "text/html"):
            payload = part.get_payload(decode=True)
            if payload:
                body += payload.decode("utf-8", errors="replace")

    body_lower = body.lower()
    for kw in URGENCY_KEYWORDS:
        if kw in body_lower:
            indicators.append(f"Urgency keyword: '{kw}'")

    urls = re.findall(r'https?://[^\s<>"\']+', body)
    for url in urls[:10]:
        if re.search(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', url):
            indicators.append(f"URL with IP address: {url[:80]}")
        if len(url) > 100:
            indicators.append(f"Unusually long URL: {url[:80]}...")

    attachments = []
    for part in msg.walk():
        fname = part.get_filename()
        if fname:
            ext = os.path.splitext(fname)[1].lower()
            attachments.append(fname)
            if ext in SUSPICIOUS_EXTENSIONS:
                indicators.append(f"Suspicious attachment: {fname}")
            if ".." in fname or ext == ".exe.pdf":
                indicators.append(f"Double extension: {fname}")

    return indicators, attachments


def analyze_email(eml_path):
    """Full spearphishing analysis of a single email."""
    headers, msg = parse_email_headers(eml_path)
    auth_issues = check_authentication(headers)
    content_indicators, attachments = check_content_indicators(msg)

    all_indicators = auth_issues + content_indicators
    score = len(all_indicators) * 15
    risk = "CRITICAL" if score >= 75 else "HIGH" if score >= 50 else "MEDIUM" if score >= 25 else "LOW"

    return {
        "file": eml_path,
        "from": headers["from"],
        "to": headers["to"],
        "subject": headers["subject"],
        "auth_issues": auth_issues,
        "content_indicators": content_indicators,
        "attachments": attachments,
        "risk_score": min(score, 100),
        "risk_level": risk,
    }


def main():
    parser = argparse.ArgumentParser(
        description="Detect spearphishing via email gateway analysis"
    )
    parser.add_argument("input", help=".eml file or directory")
    parser.add_argument("--output", "-o", help="Output JSON report")
    parser.add_argument("--verbose", "-v", action="store_true")
    args = parser.parse_args()

    print("[*] Spearphishing Detection Agent")
    results = []

    if os.path.isdir(args.input):
        for root, _, files in os.walk(args.input):
            for f in files:
                if f.lower().endswith(".eml"):
                    results.append(analyze_email(os.path.join(root, f)))
    else:
        results.append(analyze_email(args.input))

    flagged = [r for r in results if r["risk_level"] in ("HIGH", "CRITICAL")]
    report = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "emails_scanned": len(results),
        "spearphishing_detected": len(flagged),
        "results": results,
    }

    print(f"[*] Scanned {len(results)} emails, {len(flagged)} flagged")

    if args.output:
        with open(args.output, "w") as f:
            json.dump(report, f, indent=2)
        print(f"[*] Report saved to {args.output}")
    else:
        print(json.dumps(report, indent=2))


if __name__ == "__main__":
    main()
