#!/usr/bin/env bash
# ============================================================================
# run_all.sh — full RoaringKittyTracker pipeline, one command
#
# Order matters:
#   1. data pulls   (universe → weekly prices → quarterly stmts → SEC 10-Ks)
#   2. screeners    (RK first: it fills the shared yfinance cache the
#                    Burry / Kulamägi / Buffett screeners reuse)
#   3. backtests    (opt-in via --with-backtests)
#
# Every step is resumable — safe to Ctrl+C and rerun. Downloaders skip
# files fresher than their own TTLs, so reruns are cheap.
#
# Usage:
#   bash run_all.sh                    # data + all four screeners
#   bash run_all.sh --finalize-only    # rescore from cache, no network
#   bash run_all.sh --skip-data        # screeners only
#   bash run_all.sh --force-data        # re-download all source data, ignoring cache TTLs
#   bash run_all.sh --with-backtests   # also run bt_engine + bt_buffett
#   bash run_all.sh --serve            # start the dashboard when done
#
# Tunables (env vars):
#   UNIVERSE_MAX_AGE_DAYS=30   refresh us_universe.csv if older than this
# ============================================================================
set -euo pipefail
cd "$(dirname "$0")"

SKIP_DATA=0; FINALIZE_ONLY=0; WITH_BACKTESTS=0; SERVE=0; FORCE_DATA=0
for arg in "$@"; do
  case "$arg" in
    --skip-data)       SKIP_DATA=1 ;;
    --finalize-only)   FINALIZE_ONLY=1 ;;
    --force-data)      FORCE_DATA=1 ;;
    --with-backtests)  WITH_BACKTESTS=1 ;;
    --serve)           SERVE=1 ;;
    *) echo "Unknown flag: $arg"; exit 1 ;;
  esac
done

UNIVERSE_MAX_AGE_DAYS="${UNIVERSE_MAX_AGE_DAYS:-30}"
UNIVERSE_CSV="${UNIVERSE_CSV:-us_universe.csv}"

# ── Bootstrap venv ───────────────────────────────────────────────────────────
if [ ! -d .venv ]; then
  echo "── Creating virtualenv..."
  python3 -m venv .venv
fi
# shellcheck disable=SC1091
source .venv/bin/activate
pip install -q -r requirements.txt

PY=python3

# Portable file-age check (days), via python (works on macOS + Linux)
age_days() {
  $PY - "$1" <<'EOF'
import os, sys, time
p = sys.argv[1]
print(int((time.time() - os.path.getmtime(p)) / 86400) if os.path.exists(p) else 99999)
EOF
}

step() { echo; echo "════ $1 ════"; }

# ── 1. Data pulls ────────────────────────────────────────────────────────────
if [ "$SKIP_DATA" -eq 0 ] && [ "$FINALIZE_ONLY" -eq 0 ]; then

  step "1a. Universe list (refresh if > ${UNIVERSE_MAX_AGE_DAYS}d old)"
  if [ "$FORCE_DATA" -eq 1 ] || [ "$(age_days $UNIVERSE_CSV)" -gt "$UNIVERSE_MAX_AGE_DAYS" ]; then
    $PY download_us_universe_marketcap.py --out "$UNIVERSE_CSV" --skip-market-caps
  else
    echo "  $UNIVERSE_CSV is fresh — skipping."
  fi

  step "1b. Weekly price history (internal 23h TTL, ~10-15 min first run)"
  if [ "$FORCE_DATA" -eq 1 ]; then
    $PY download_weekly_history.py --universe "$UNIVERSE_CSV" --force
  else
    $PY download_weekly_history.py --universe "$UNIVERSE_CSV"
  fi

  step "1c. Quarterly financials (internal 7d TTL, ~60-90 min first run)"
  if [ "$FORCE_DATA" -eq 1 ]; then
    $PY download_quarterly_financials.py --universe "$UNIVERSE_CSV" --force
  else
    $PY download_quarterly_financials.py --universe "$UNIVERSE_CSV"
  fi

  step "1d. SEC 10-K fundamentals (internal 30d TTL, ~20 min first run)"
  if [ "$FORCE_DATA" -eq 1 ]; then
    $PY download_sec_fundamentals.py --universe_csv "$UNIVERSE_CSV" --max_age_days 0
  else
    $PY download_sec_fundamentals.py --universe_csv "$UNIVERSE_CSV"
  fi
fi

# ── 2. Screeners (RK first — it fills the shared yfinance cache) ────────────
run_screener() {  # $1 = script name (label inferred)
  step "2. $1"
  if [ "$FINALIZE_ONLY" -eq 1 ]; then
    $PY "$1" --config config.yaml --finalize_only
  else
    $PY "$1" --config config.yaml --universe_csv "$UNIVERSE_CSV" --resume
  fi
}

if [ "$FINALIZE_ONLY" -eq 1 ]; then
  step "2. Roaring Kitty screener (finalize only)"
  $PY rk_tracker.py --config config.yaml --finalize_only
else
  step "2. Roaring Kitty screener (slowest on first run — fills shared cache)"
  $PY run_universe.py --universe_csv "$UNIVERSE_CSV" --resume
fi
run_screener burry_tracker.py
run_screener kulamagi_tracker.py
run_screener buffett_tracker.py

step "2b. Export ticker-only scan outputs"
$PY export_scan_tickers.py

step "2c. Combined cross-screener turnaround setups"
$PY combined_tracker.py || echo "  (combined tracker skipped — check exports/weekly data)"

step "2d. Default dashboard watchlist"
$PY export_default_watchlist.py

# ── 3. Backtests (opt-in) ────────────────────────────────────────────────────
if [ "$WITH_BACKTESTS" -eq 1 ]; then
  step "3a. RK screener backtest (strict PIT + costs)"
  $PY bt_engine.py --strict_pit

  step "3b. Buffett screener backtest (SEC filed-date PIT)"
  $PY bt_buffett.py --top_n 20
fi

# ── Done ─────────────────────────────────────────────────────────────────────
echo
echo "════ Pipeline complete ════"
echo "Outputs: data/outputs/*.csv"
if [ "$SERVE" -eq 1 ]; then
  echo "Starting dashboard → http://localhost:8765/dashboard.html"
  exec $PY serve.py
else
  echo "Dashboard: python serve.py  →  http://localhost:8765/dashboard.html"
fi
