#!/usr/bin/env bash
# kicad-build — orchestrator for circuit_toolkit + kicad-cli.
#
# Usage:
#   ./kicad-build <board-dir> [--erc] [--drc] [--gerber] [--bom] [--schematic] [--sim] [--all]
#
# Steps (all are optional, --all runs everything):
#   1. circuit_toolkit build (generates .kicad_sch + .kicad_pcb)
#   2. kicad-cli sch erc (electrical rules check)
#   3. kicad-cli pcb drc (design rules check)
#   4. kicad-cli pcb export gerber/drill/position
#   5. kicad-cli sch export bom/pdf/netlist
#   6. SPICE simulation (if sim/ present)
#
# Requires:
#   - KiCad.app installed (for pcbnew)
#   - kicad-cli on PATH (homebrew: brew install kicad)
#   - ngspice on PATH (for --sim, brew install ngspice)
#   - netlistsvg on PATH (for --schematic SVG, npm install -g netlistsvg)
#   - circuit_toolkit installed into KiCad's Python (run install-kicad-toolkit.sh)

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
KICAD_PYTHON="$SCRIPT_DIR/kicad-python"
KICAD_CLI=$(command -v kicad-cli 2>/dev/null || echo "")

# circuit_toolkit paths
TOOLKIT_SRC="$PROJECT_ROOT/kicad-claude-toolkit/python/circuit_toolkit"
TOOLKIT_PY="$TOOLKIT_SRC/circuit_toolkit"

# Output directory (relative to board dir)
OUTPUT_DIR=""

usage() {
    echo "Usage: $0 <board-dir> [--erc] [--drc] [--gerber] [--bom] [--schematic] [--sim] [--all]"
    echo ""
    echo "  --erc       Run ERC on generated schematic"
    echo "  --drc       Run DRC on generated PCB"
    echo "  --gerber    Export Gerber + drill + position files"
    echo "  --bom       Generate BOM (flat + JLCPCB)"
    echo "  --schematic Generate schematic SVG via netlistsvg"
    echo "  --sim       Run SPICE simulations (if sim/ present)"
    echo "  --all       Run all steps (default)"
    echo "  --dry-run   Print planned commands without executing"
    exit 1
}

# Parse args
BOARD_DIR=""
DO_ERC=false
DO_DRC=false
DO_GERBER=false
DO_BOM=false
DO_SCHEMATIC=false
DO_SIM=false
DO_ALL=true
DRY_RUN=false

for arg in "$@"; do
    case "$arg" in
        --erc)       DO_ERC=true;       DO_ALL=false;;
        --drc)       DO_DRC=true;       DO_ALL=false;;
        --gerber)    DO_GERBER=true;    DO_ALL=false;;
        --bom)       DO_BOM=true;       DO_ALL=false;;
        --schematic) DO_SCHEMATIC=true; DO_ALL=false;;
        --sim)       DO_SIM=true;       DO_ALL=false;;
        --dry-run)   DRY_RUN=true;;
        -h|--help)   usage;;
        -*)
            echo "Unknown option: $arg" >&2
            usage;;
        *)
            if [ -z "$BOARD_DIR" ]; then
                BOARD_DIR="$arg"
            else
                echo "Unexpected argument: $arg" >&2
                usage
            fi
            ;;
    esac
done

if [ -z "$BOARD_DIR" ]; then
    echo "ERROR: board directory required" >&2
    usage
fi

BOARD_DIR="$(cd "$BOARD_DIR" && pwd)"
OUTPUT_DIR="$BOARD_DIR/output"

if $DO_ALL; then
    DO_ERC=true; DO_DRC=true; DO_GERBER=true; DO_BOM=true; DO_SCHEMATIC=true
fi

# ── Pre-flight checks ──────────────────────────────────────────────────
check_kicad_python() {
    if ! $DRY_RUN && ! bash "$KICAD_PYTHON" -c "import pcbnew" 2>/dev/null; then
        echo "ERROR: pcbnew not available. Run KiCad.app at least once, then retry." >&2
        exit 1
    fi
}

check_kicad_cli() {
    if [ -z "$KICAD_CLI" ]; then
        echo "ERROR: kicad-cli not on PATH. Install via: brew install kicad" >&2
        exit 1
    fi
}

# ── Step 1: circuit_toolkit build ──────────────────────────────────────
step_build() {
    local build_script="$BOARD_DIR/build.py"
    if [ ! -f "$build_script" ]; then
        echo "SKIP build: no build.py in $BOARD_DIR"
        return 0
    fi
    echo "=== Step 1: circuit_toolkit build ==="
    if $DRY_RUN; then
        echo "  [dry-run] KiCad Python $KICAD_PYTHON"
        echo "  [dry-run] cd $BOARD_DIR && $KICAD_PYTHON build.py"
        return 0
    fi
    mkdir -p "$OUTPUT_DIR"
    pushd "$BOARD_DIR" >/dev/null
    PYTHONPATH="$TOOLKIT_SRC:$PYTHONPATH" \
        bash "$KICAD_PYTHON" build.py
    popd >/dev/null
    echo "  -> $OUTPUT_DIR/"
}

# ── Step 2: ERC ────────────────────────────────────────────────────────
step_erc() {
    local sch="$BOARD_DIR/*.kicad_sch"
    sch=$(ls $sch 2>/dev/null | head -1 || true)
    if [ -z "$sch" ]; then
        echo "SKIP ERC: no .kicad_sch found"
        return 0
    fi
    echo "=== Step 2: ERC ==="
    if $DRY_RUN; then
        echo "  [dry-run] $KICAD_CLI sch erc $sch"
        return 0
    fi
    mkdir -p "$OUTPUT_DIR/erc"
    $KICAD_CLI sch erc "$sch" --output "$OUTPUT_DIR/erc/erc_report.txt" 2>&1 || true
    echo "  -> $OUTPUT_DIR/erc/"
}

# ── Step 3: DRC ────────────────────────────────────────────────────────
step_drc() {
    local pcb="$BOARD_DIR/*.kicad_pcb"
    pcb=$(ls $pcb 2>/dev/null | head -1 || true)
    if [ -z "$pcb" ]; then
        echo "SKIP DRC: no .kicad_pcb found"
        return 0
    fi
    echo "=== Step 3: DRC ==="
    if $DRY_RUN; then
        echo "  [dry-run] $KICAD_CLI pcb drc $pcb"
        return 0
    fi
    mkdir -p "$OUTPUT_DIR/drc"
    $KICAD_CLI pcb drc "$pcb" --output "$OUTPUT_DIR/drc/drc_report.html" 2>&1 || true
    echo "  -> $OUTPUT_DIR/drc/"
}

# ── Step 4: Gerber/Drill/Position export ──────────────────────────────
step_gerber() {
    local pcb="$BOARD_DIR/*.kicad_pcb"
    pcb=$(ls $pcb 2>/dev/null | head -1 || true)
    if [ -z "$pcb" ]; then
        echo "SKIP gerber: no .kicad_pcb found"
        return 0
    fi
    echo "=== Step 4: Gerber + Drill + Position export ==="
    if $DRY_RUN; then
        echo "  [dry-run] $KICAD_CLI pcb export gerbers $pcb --output $OUTPUT_DIR/fab/gerber"
        return 0
    fi
    mkdir -p "$OUTPUT_DIR/fab/gerber"
    $KICAD_CLI pcb export gerbers "$pcb" --output "$OUTPUT_DIR/fab/gerber" 2>&1
    $KICAD_CLI pcb export drill "$pcb" --output "$OUTPUT_DIR/fab/gerber" 2>&1
    $KICAD_CLI pcb export pos "$pcb" --output "$OUTPUT_DIR/fab/positions.csv" 2>&1
    echo "  -> $OUTPUT_DIR/fab/"
}

# ── Step 5: BOM + schematic PDF + netlist ─────────────────────────────
step_bom() {
    local sch="$BOARD_DIR/*.kicad_sch"
    sch=$(ls $sch 2>/dev/null | head -1 || true)
    if [ -z "$sch" ]; then
        echo "SKIP bom: no .kicad_sch found"
        return 0
    fi
    echo "=== Step 5: BOM + schematic PDF + netlist ==="
    if $DRY_RUN; then
        echo "  [dry-run] $KICAD_CLI sch export bom $sch --output $OUTPUT_DIR/fab"
        return 0
    fi
    mkdir -p "$OUTPUT_DIR/fab"
    $KICAD_CLI sch export bom "$sch" --output "$OUTPUT_DIR/fab" 2>&1
    $KICAD_CLI sch export pdf "$sch" --output "$OUTPUT_DIR/schematic.pdf" 2>&1
    $KICAD_CLI sch export "$sch" --format netlist --output "$OUTPUT_DIR/fab/netlist.xml" 2>&1
    echo "  -> $OUTPUT_DIR/fab/"
}

# ── Step 6: SPICE simulation ──────────────────────────────────────────
step_sim() {
    if [ ! -d "$BOARD_DIR/sim" ]; then
        echo "SKIP sim: no sim/ directory"
        return 0
    fi
    echo "=== Step 6: SPICE simulation ==="
    if $DRY_RUN; then
        echo "  [dry-run] ngspice -b $BOARD_DIR/sim/*.cir"
        return 0
    fi
    if ! command -v ngspice &>/dev/null; then
        echo "SKIP sim: ngspice not on PATH (brew install ngspice)"
        return 0
    fi
    mkdir -p "$OUTPUT_DIR/sim"
    for cir in "$BOARD_DIR"/sim/*.cir; do
        echo "  sim: $(basename "$cir")"
        ngspice -b -r "$OUTPUT_DIR/sim/$(basename "$cir" .cir).raw" "$cir" 2>&1 || true
    done
    echo "  -> $OUTPUT_DIR/sim/"
}

# ── Run ────────────────────────────────────────────────────────────────
echo "kicad-build: $BOARD_DIR"
echo "  KiCad Python: $KICAD_PYTHON"
echo "  kicad-cli:    $KICAD_CLI"
echo "  output:       $OUTPUT_DIR"
echo ""

check_kicad_python
if [ -n "$KICAD_CLI" ]; then
    : # ok
else
    echo "WARNING: kicad-cli not found (ERC/DRC/gerber/bom will be skipped)"
fi

step_build
$DO_ERC && step_erc
$DO_DRC && step_drc
$DO_GERBER && step_gerber
$DO_BOM && step_bom
$DO_SIM && step_sim

echo ""
echo "=== Done ==="
echo "Output: $OUTPUT_DIR/"
ls -la "$OUTPUT_DIR/" 2>/dev/null || true
