#!/usr/bin/env python3
"""Crea un inventario prudente di file EML senza leggere i corpi dei messaggi."""

from __future__ import annotations

import argparse
import csv
import hashlib
from email import policy
from email.parser import BytesParser
from pathlib import Path


def short_hash(value: str) -> str:
    return hashlib.sha256(value.encode("utf-8", errors="replace")).hexdigest()[:16]


def attachment_summary(message) -> tuple[int, str]:
    count = 0
    extensions: dict[str, int] = {}
    for part in message.walk():
        if part.get_content_disposition() != "attachment":
            continue
        count += 1
        suffix = Path(part.get_filename() or "").suffix.lower() or "[senza-estensione]"
        extensions[suffix] = extensions.get(suffix, 0) + 1
    summary = "; ".join(f"{key}:{extensions[key]}" for key in sorted(extensions))
    return count, summary


def inspect_eml(path: Path, root: Path, include_subject: bool) -> dict[str, str | int]:
    with path.open("rb") as handle:
        message = BytesParser(policy=policy.default).parse(handle, headersonly=False)
    message_id = str(message.get("Message-ID", ""))
    subject = str(message.get("Subject", ""))
    sender = str(message.get("From", ""))
    date = str(message.get("Date", ""))
    fingerprint = short_hash("|".join((message_id, sender, date, subject)))
    attachment_count, attachment_types = attachment_summary(message)
    row: dict[str, str | int] = {
        "file": path.relative_to(root).as_posix(),
        "message_fingerprint": fingerprint,
        "date_header": date,
        "attachment_count": attachment_count,
        "attachment_types": attachment_types,
    }
    if include_subject:
        row["subject"] = subject
    return row


def build_inventory(root: Path, include_subject: bool = False) -> list[dict[str, str | int]]:
    return [inspect_eml(path, root, include_subject) for path in sorted(root.rglob("*.eml"))]


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("source", type=Path, help="Cartella locale contenente file .eml")
    parser.add_argument("--output", type=Path, required=True, help="CSV da creare")
    parser.add_argument("--include-subject", action="store_true", help="Include gli oggetti: controllare prima di condividere")
    args = parser.parse_args()
    if not args.source.is_dir():
        parser.error("La sorgente deve essere una cartella esistente.")
    rows = build_inventory(args.source.resolve(), args.include_subject)
    args.output.parent.mkdir(parents=True, exist_ok=True)
    fieldnames = ["file", "message_fingerprint", "date_header", "attachment_count", "attachment_types"]
    if args.include_subject:
        fieldnames.append("subject")
    with args.output.open("w", newline="", encoding="utf-8") as handle:
        writer = csv.DictWriter(handle, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)
    print(f"Inventariati {len(rows)} file EML in {args.output}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
