#!/usr/bin/env bash
set -euo pipefail

if [[ $# -lt 2 || $# -gt 5 ]]; then
  echo "Usage: $0 <ours.csv> <record.csv> [summary.md] [only_in_ours.csv] [only_in_record.csv]" >&2
  exit 2
fi

OURS_CSV="$1"
RECORD_CSV="$2"
SUMMARY_MD="${3:-}"
ONLY_IN_OURS_CSV="${4:-}"
ONLY_IN_RECORD_CSV="${5:-}"

if [[ -z "$SUMMARY_MD" ]]; then
  SUMMARY_MD="$(dirname "$OURS_CSV")/$(basename "$OURS_CSV" .csv)_vs_routinator_summary.md"
fi
if [[ -z "$ONLY_IN_OURS_CSV" ]]; then
  ONLY_IN_OURS_CSV="$(dirname "$OURS_CSV")/$(basename "$OURS_CSV" .csv)_only_in_ours.csv"
fi
if [[ -z "$ONLY_IN_RECORD_CSV" ]]; then
  ONLY_IN_RECORD_CSV="$(dirname "$OURS_CSV")/$(basename "$OURS_CSV" .csv)_only_in_record.csv"
fi

python3 - "$OURS_CSV" "$RECORD_CSV" "$SUMMARY_MD" "$ONLY_IN_OURS_CSV" "$ONLY_IN_RECORD_CSV" <<'PY'
import csv
import ipaddress
import sys
from pathlib import Path

ours_csv = Path(sys.argv[1])
record_csv = Path(sys.argv[2])
summary_md = Path(sys.argv[3])
only_in_ours_csv = Path(sys.argv[4])
only_in_record_csv = Path(sys.argv[5])


def normalize_row(row: dict):
    asn = row["ASN"].strip().upper()
    prefix = row["IP Prefix"].strip()
    max_len = str(int(row["Max Length"]))
    ta = row["Trust Anchor"].strip()
    network = ipaddress.ip_network(prefix, strict=False)
    return {
        "ASN": asn,
        "IP Prefix": str(network),
        "Max Length": max_len,
        "Trust Anchor": ta,
    }


def read_rows(path: Path):
    with path.open(encoding="utf-8", newline="") as f:
        rows = [normalize_row(r) for r in csv.DictReader(f)]
    return rows


def row_key(row: dict):
    network = ipaddress.ip_network(row["IP Prefix"], strict=False)
    return (
        row["ASN"],
        network.version,
        int(network.network_address),
        network.prefixlen,
        int(row["Max Length"]),
        row["Trust Anchor"],
    )


def write_rows(path: Path, rows):
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("w", encoding="utf-8", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=["ASN", "IP Prefix", "Max Length", "Trust Anchor"])
        writer.writeheader()
        for row in rows:
            writer.writerow(row)

ours = read_rows(ours_csv)
record = read_rows(record_csv)
ours_map = {row_key(r): r for r in ours}
record_map = {row_key(r): r for r in record}
only_in_ours = [ours_map[k] for k in sorted(set(ours_map) - set(record_map))]
only_in_record = [record_map[k] for k in sorted(set(record_map) - set(ours_map))]
intersection = len(set(ours_map) & set(record_map))

write_rows(only_in_ours_csv, only_in_ours)
write_rows(only_in_record_csv, only_in_record)

summary_md.parent.mkdir(parents=True, exist_ok=True)
summary = []
summary.append("# Replay vs Routinator VRP Compare\n\n")
summary.append(f"- ours_csv: `{ours_csv}`\n")
summary.append(f"- record_csv: `{record_csv}`\n")
summary.append(f"- only_in_ours_csv: `{only_in_ours_csv}`\n")
summary.append(f"- only_in_record_csv: `{only_in_record_csv}`\n\n")
summary.append("| metric | value |\n")
summary.append("|---|---:|\n")
summary.append(f"| ours_total | {len(ours_map)} |\n")
summary.append(f"| record_total | {len(record_map)} |\n")
summary.append(f"| intersection | {intersection} |\n")
summary.append(f"| only_in_ours | {len(only_in_ours)} |\n")
summary.append(f"| only_in_record | {len(only_in_record)} |\n")
summary_md.write_text("".join(summary), encoding="utf-8")
print(summary_md)
PY

echo "== compare complete ==" >&2
echo "- summary: $SUMMARY_MD" >&2
echo "- only_in_ours: $ONLY_IN_OURS_CSV" >&2
echo "- only_in_record: $ONLY_IN_RECORD_CSV" >&2
