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

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RULES_FILE="${HOMELAB_IMPACT_RULES:-${REPO_ROOT}/infra/jeannie-impact/rules.tsv}"

usage() {
    cat <<'EOF'
Usage: ./jeannie impact [--since REF] [PATH...]

Explain which homelab areas are touched by changed files or explicit paths.
Default mode analyzes the current working tree diff.
EOF
}

since=""
paths=()
while [ "$#" -gt 0 ]; do
    case "$1" in
        --since)
            since="${2:-}"
            shift 2
            ;;
        -h|--help|help)
            usage
            exit 0
            ;;
        *)
            paths+=("$1")
            shift
            ;;
    esac
done

if [ ! -s "$RULES_FILE" ]; then
    echo "Missing impact rules: $RULES_FILE" >&2
    exit 1
fi

if [ "${#paths[@]}" -eq 0 ]; then
    if [ -n "$since" ]; then
        mapfile -t paths < <(git -C "$REPO_ROOT" diff --name-only "$since"...HEAD)
    else
        mapfile -t paths < <(git -C "$REPO_ROOT" status --short | awk '{print $NF}')
    fi
fi

if [ "${#paths[@]}" -eq 0 ]; then
    echo "No changed files or paths to analyze."
    exit 0
fi

python3 - "$RULES_FILE" "${paths[@]}" <<'PY'
import csv
import sys

rules_file = sys.argv[1]
paths = [path.strip() for path in sys.argv[2:] if path.strip()]

with open(rules_file, encoding="utf-8", newline="") as handle:
    rules = list(csv.DictReader(handle, delimiter="\t"))

matches = []
for path in paths:
    normalized = path.removeprefix("./")
    for rule in rules:
        pattern = rule["pattern"]
        if normalized == pattern.rstrip("/") or normalized.startswith(pattern):
            matches.append((normalized, rule))

print("Jeannie Impact")
print("==============")
print("Files:")
for path in paths:
    print(f"  {path}")

if not matches:
    print("\nNo specific impact rule matched.")
    print("Validate:")
    print("  ./jeannie validate")
    raise SystemExit(0)

seen = set()
print("\nImpacted Areas")
for path, rule in matches:
    key = (rule["area"], rule["risk"])
    if key in seen:
        continue
    seen.add(key)
    print(f"\n- {rule['area']}")
    print(f"  risk: {rule['risk']}")
    print("  touches:")
    for item in rule["touches"].split(";"):
        print(f"    - {item}")
    print("  validate:")
    for command in rule["validate"].split(";"):
        print(f"    {command}")
    if rule["apply"] != "none":
        print("  apply path:")
        for command in rule["apply"].split(";"):
            print(f"    {command}")
    else:
        print("  apply path: none")
PY
