#!/usr/bin/env python3
"""AI-assisted log anomaly detection using scikit-learn IsolationForest.

Designed for defensive monitoring on logs your organization owns or is authorized
to process. Input CSV should include timestamp, source, event_type, status, and
message columns where available.
"""

from __future__ import annotations

import argparse
import csv
from pathlib import Path

from sklearn.ensemble import IsolationForest  # type: ignore
from sklearn.feature_extraction.text import TfidfVectorizer  # type: ignore
from sklearn.pipeline import make_pipeline  # type: ignore


def main() -> int:
    parser = argparse.ArgumentParser(description="Flag unusual log messages for analyst review.")
    parser.add_argument("csv_file", type=Path)
    parser.add_argument("--output", type=Path, default=Path("log_anomalies.csv"))
    parser.add_argument("--contamination", type=float, default=0.03)
    args = parser.parse_args()

    rows = list(csv.DictReader(args.csv_file.open("r", encoding="utf-8", newline="")))
    texts = [" ".join(str(row.get(key, "")) for key in ["source", "event_type", "status", "message"]) for row in rows]
    model = make_pipeline(
        TfidfVectorizer(max_features=2000, ngram_range=(1, 2)),
        IsolationForest(contamination=args.contamination, random_state=42),
    )
    predictions = model.fit_predict(texts)
    anomalies = [row | {"anomaly_score": "review"} for row, pred in zip(rows, predictions) if pred == -1]
    with args.output.open("w", newline="", encoding="utf-8") as handle:
        fieldnames = list(rows[0].keys()) + ["anomaly_score"] if rows else ["anomaly_score"]
        writer = csv.DictWriter(handle, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(anomalies)
    print(f"Flagged {len(anomalies)} anomalies for analyst review in {args.output}")
    return 0


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