#!/bin/bash
set -euo pipefail

# --- Resolve to this script's directory ---
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_DIR="$SCRIPT_DIR/venv"
PYTHON_SCRIPT="export_w1hd9_raw.py"
OUTPUT_DIR="$SCRIPT_DIR"
CALLSIGN="W1HD-9"

# 8-hour window in UTC
START_TIME=$(date -u -d "8 hours ago" +"%Y-%m-%d %H:%M")
END_TIME=$(date -u +"%Y-%m-%d %H:%M")

# Safe filename
START_SAFE="${START_TIME//[: ]/_}"
END_SAFE="${END_TIME//[: ]/_}"
OUTPUT_FILE="w1hd9_raw_${START_SAFE}_${END_SAFE}.csv"

# --- System deps ---
sudo apt-get update
sudo apt-get install -y google-chrome-stable python3-venv python3-full

# --- Work as bbl (venv + run) ---
set -x
sudo -u bbl -H bash -lc '
  set -euo pipefail
  SCRIPT_DIR="'"$SCRIPT_DIR"'"
  VENV_DIR="'"$VENV_DIR"'"
  OUTPUT_DIR="'"$OUTPUT_DIR"'"
  PYTHON_SCRIPT="'"$PYTHON_SCRIPT"'"
  CALLSIGN="'"$CALLSIGN"'"
  START_TIME="'"$START_TIME"'"
  END_TIME="'"$END_TIME"'"
  OUTPUT_FILE="'"$OUTPUT_FILE"'"

  # Load env (credentials) explicitly
  if [ -f "$HOME/.bashrc" ]; then
    # shellcheck disable=SC1090
    source "$HOME/.bashrc"
  fi
  # Optional extra file, if you keep secrets there:
  if [ -f "$HOME/.aprs.env" ]; then
    set -a
    # shellcheck disable=SC1090
    source "$HOME/.aprs.env"
    set +a
  fi

  echo "APRS_USERNAME=${APRS_USERNAME-<unset>}"
  if [ -z "${APRS_PASSWORD-}" ]; then
    echo "ERROR: APRS_PASSWORD not set for user bbl. Put it in ~/.bashrc or ~/.aprs.env" >&2
    exit 2
  fi

  # Create venv if needed
  if [ ! -d "$VENV_DIR" ]; then
    python3 -m venv "$VENV_DIR"
  fi
  source "$VENV_DIR/bin/activate"

  python -m pip install --upgrade pip
  pip install --upgrade selenium webdriver-manager

  # Write Python driver (CAREFUL: terminator must be PYEOF with no spaces)
  cat > "$SCRIPT_DIR/$PYTHON_SCRIPT" <<PYEOF
#!/usr/bin/env python3
import os, time, glob, sys, traceback
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options as ChromeOptions

USERNAME = os.environ.get("APRS_USERNAME")
PASSWORD = os.environ.get("APRS_PASSWORD")
OUTPUT_DIR = os.environ.get("OUTPUT_DIR", ".")
CALLSIGN   = os.environ.get("CALLSIGN", "W1HD-9")
START_TIME = os.environ.get("START_TIME")
END_TIME   = os.environ.get("END_TIME")
OUTPUT_FILE= os.environ.get("OUTPUT_FILE", "export.csv")
DEBUG_DIR  = os.path.join(OUTPUT_DIR, "debug")
os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(DEBUG_DIR, exist_ok=True)

def snap(tag, driver):
    try:
        ts = str(int(time.time()))
        png  = os.path.join(DEBUG_DIR, f"{ts}_{tag}.png")
        html = os.path.join(DEBUG_DIR, f"{ts}_{tag}.html")
        driver.save_screenshot(png)
        open(html, "w", encoding="utf-8").write(driver.page_source)
        print("DEBUG wrote", png, "and", html)
    except Exception as e:
        print("DEBUG snap failed:", e)

def die(msg, driver=None):
    print("ERROR:", msg)
    if driver: snap("exception", driver)
    sys.exit(1)

if not USERNAME or not PASSWORD:
    die("APRS_USERNAME/APRS_PASSWORD missing in environment")

prefs = {
    "download.default_directory": OUTPUT_DIR,
    "download.prompt_for_download": False,
    "profile.default_content_setting_values.automatic_downloads": 1,
    "safebrowsing.enabled": True,
}
opts = ChromeOptions()
opts.add_argument("--headless=new")
opts.add_argument("--no-sandbox")
opts.add_argument("--disable-dev-shm-usage")
opts.add_argument("--disable-gpu")
opts.add_argument("--window-size=1280,1200")
opts.add_argument("--disable-blink-features=AutomationControlled")
opts.add_argument("--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121 Safari/537.36")
opts.add_experimental_option("prefs", prefs)

driver = None
try:
    driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=opts)
    wait = WebDriverWait(driver, 25)
    try:
        caps = driver.capabilities
        print("Chrome version:", caps.get("browserVersion"))
        print("Driver:", caps.get("chrome", {}).get("chromedriverVersion"))
    except Exception:
        pass

    try:
        driver.execute_cdp_cmd("Page.setDownloadBehavior", {"behavior": "allow", "downloadPath": OUTPUT_DIR})
    except Exception:
        pass

    driver.get("https://aprs.fi/")
    snap("home", driver)
    time.sleep(1)

    login = wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(., 'Login')]")))
    login.click()
    time.sleep(1)
    snap("login_page", driver)

    user = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@id='username' or @name='username' or @name='login']")))
    pw   = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@id='password' or @name='password']")))
    user.clear(); user.send_keys(USERNAME)
    time.sleep(0.3)
    pw.clear(); pw.send_keys(PASSWORD); pw.send_keys(Keys.RETURN)
    time.sleep(2)
    snap("after_login", driver)

    driver.get("https://aprs.fi/export/")
    time.sleep(1)
    snap("export_page", driver)

    call_el  = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@name='call' or @id='call' or contains(@placeholder,'callsign')]")))
    start_el = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@name='start' or @id='start']")))
    end_el   = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@name='end' or @id='end']")))

    call_el.clear();  call_el.send_keys(CALLSIGN)
    start_el.clear(); start_el.send_keys(START_TIME)
    end_el.clear();   end_el.send_keys(END_TIME)
    snap("filled_form", driver)

    try:
        radios = driver.find_elements(By.XPATH, "//input[@type='radio' and (contains(@value,'csv') or contains(@id,'csv'))]")
        if radios:
            radios[0].click()
    except Exception:
        pass

    try:
        btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(.,'Export') or contains(.,'Download') or @type='submit']")))
        btn.click()
    except Exception:
        try:
            form = driver.find_element(By.XPATH, "//form[.//*[@name='call']]")
            form.submit()
        except Exception:
            snap("no_submit", driver)
            die("Could not locate export/submit control", driver)

    time.sleep(2)
    snap("after_submit", driver)

    before = set(glob.glob(os.path.join(OUTPUT_DIR, "*")))
    deadline = time.time() + 40
    downloaded = None
    while time.time() < deadline:
        time.sleep(1)
        after = set(glob.glob(os.path.join(OUTPUT_DIR, "*")))
        new = [f for f in (after - before) if not f.endswith(".crdownload")]
        if new:
            downloaded = sorted(new, key=os.path.getmtime)[-1]
            break

    if not downloaded:
        snap("no_download", driver)
        die(f"No file appeared in {OUTPUT_DIR}", driver)

    dest = os.path.join(OUTPUT_DIR, OUTPUT_FILE)
    if downloaded != dest:
        try:
            os.replace(downloaded, dest)
        except Exception as e:
            print("Downloaded but rename failed:", e)
            dest = downloaded
    print("Saved", dest)

except Exception:
    traceback.print_exc()
    die("Unhandled exception", driver)
finally:
    if driver:
        driver.quit()
PYEOF

  chmod +x "$SCRIPT_DIR/$PYTHON_SCRIPT"

  export OUTPUT_DIR="$OUTPUT_DIR"
  export CALLSIGN="$CALLSIGN"
  export START_TIME="$START_TIME"
  export END_TIME="$END_TIME"
  export OUTPUT_FILE="$OUTPUT_FILE"

  echo "Running export at $(date -u) ..."
  set -e
  "$VENV_DIR/bin/python" "$SCRIPT_DIR/$PYTHON_SCRIPT"
'
set +x

echo "Done. Check: $OUTPUT_DIR/$OUTPUT_FILE (and $OUTPUT_DIR/debug/ for screenshots & HTML)"
