#!/bin/bash
# SkyBoss ATC installer.
# The install guide on skybossatc.com matches these steps.
#
#   curl -sSL https://skybossatc.com/install -o skyboss-install.sh
#   less skyboss-install.sh
#   SKYBOSS_LICENSE_KEY='your-key' bash skyboss-install.sh
#
# The Pi app is downloaded only after the license key checks out.
# There is no public tarball and no git remote in this script.

set -euo pipefail

if [ -z "${SKYBOSS_LICENSE_KEY:-}" ]; then
    echo "License key required."
    echo "SkyBoss ATC downloads only with the license key from your purchase."
    echo "Run: SKYBOSS_LICENSE_KEY='your-key' bash skyboss-install.sh"
    exit 1
fi

if ! printf '%s' "${SKYBOSS_LICENSE_KEY}" | grep -Eq '^[A-Za-z0-9-]{8,200}$'; then
    echo "Invalid license key."
    exit 1
fi

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

INSTALL_DIR="${HOME}/skyboss-atc"
DOWNLOAD_API="${SKYBOSS_DOWNLOAD_API:-https://skybossatc.com/api/download}"
SERVICE_NAME="skyboss-atc"
PORT=8000

echo ""
echo -e "${CYAN}SkyBoss ATC — Installer${NC}"
echo ""

if ! command -v curl >/dev/null 2>&1 || ! command -v python3 >/dev/null 2>&1 || ! command -v tar >/dev/null 2>&1 || ! python3 -c 'import venv' >/dev/null 2>&1; then
    echo -e "${YELLOW}Installing curl, Python 3, and tar...${NC}"
    sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
    sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq curl python3 python3-venv python3-pip tar
fi

api_error() {
    python3 - "$1" <<'PY'
import json
import sys

path = sys.argv[1]
try:
    data = json.load(open(path, encoding="utf-8"))
except (OSError, json.JSONDecodeError):
    print("License server unreachable.")
    raise SystemExit(0)
err = data.get("error") if isinstance(data, dict) else None
if isinstance(err, str) and err.strip():
    print(err.strip())
else:
    print("License server unreachable.")
PY
}

echo -e "${YELLOW}Checking the license key...${NC}"

BODY_FILE=$(mktemp)
HTTP_CODE=$(curl -sS --max-time 30 -o "${BODY_FILE}" -w '%{http_code}' \
    -X POST "${DOWNLOAD_API}" \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    --data "$(python3 -c 'import json, os; print(json.dumps({"license_key": os.environ["SKYBOSS_LICENSE_KEY"]}))')" \
    ) || {
    echo "License server unreachable."
    rm -f "${BODY_FILE}"
    exit 1
}

if [ "${HTTP_CODE}" != "200" ]; then
    api_error "${BODY_FILE}"
    rm -f "${BODY_FILE}"
    exit 1
fi

DOWNLOAD_URL=$(python3 - "${BODY_FILE}" <<'PY'
import json
import sys

data = json.load(open(sys.argv[1], encoding="utf-8"))
url = data.get("download_url") if isinstance(data, dict) else None
if not isinstance(url, str):
    raise SystemExit(1)
print(url)
PY
) || {
    echo "Download link was not issued by the SkyBoss install service."
    rm -f "${BODY_FILE}"
    exit 1
}
rm -f "${BODY_FILE}"

API_ORIGIN="${DOWNLOAD_API%/api/download}"
case "${DOWNLOAD_URL}" in
    "${API_ORIGIN}/api/download?token="*) ;;
    *)
        echo "Download link was not issued by the SkyBoss install service."
        exit 1
        ;;
esac

echo ""
echo -e "${YELLOW}Detecting ADS-B receiver...${NC}"

RECEIVER_URL=""
RECEIVER_FOUND=false

for url in "http://localhost:8080/data/aircraft.json" "http://localhost:80/data/aircraft.json" "http://localhost:30003" "http://127.0.0.1:8080/data/aircraft.json"; do
    if curl -s --connect-timeout 2 "${url}" > /dev/null 2>&1; then
        RECEIVER_URL="${url}"
        RECEIVER_FOUND=true
        break
    fi
done

if [ "${RECEIVER_FOUND}" = true ]; then
    echo -e "  Receiver found: ${GREEN}${RECEIVER_URL}${NC}"
else
    echo -e "  ${YELLOW}No local receiver detected.${NC}"
    echo "  Network fill can draw aircraft the antenna missed when fill is available."
    echo "  It does not replace a receiver. Go-around alerts use your antenna only."
    echo "  You can set the receiver URL later in config/settings.yaml."
    RECEIVER_URL="http://localhost:8080/data/aircraft.json"
fi

if systemctl is-active --quiet dump1090-fa 2>/dev/null; then
    echo -e "  Decoder: ${GREEN}dump1090-fa (running)${NC}"
elif systemctl is-active --quiet readsb 2>/dev/null; then
    echo -e "  Decoder: ${GREEN}readsb (running)${NC}"
else
    echo -e "  Decoder: ${YELLOW}not detected (will work once dump1090-fa or readsb is started)${NC}"
fi

echo ""
echo -e "${YELLOW}Downloading SkyBoss ATC...${NC}"

ARCHIVE=$(mktemp)
HEADERS=$(mktemp)
ARCHIVE_CODE=$(curl -sS --max-time 180 -D "${HEADERS}" -o "${ARCHIVE}" -w '%{http_code}' "${DOWNLOAD_URL}") || {
    echo "Download link is invalid or expired."
    rm -f "${ARCHIVE}" "${HEADERS}"
    exit 1
}
if [ "${ARCHIVE_CODE}" = "302" ] || [ "${ARCHIVE_CODE}" = "303" ] || [ "${ARCHIVE_CODE}" = "307" ]; then
    BLOB_URL=$(python3 - "${HEADERS}" <<'PY'
import sys
from urllib.parse import urlparse

text = open(sys.argv[1], encoding="utf-8", errors="replace").read()
location = ""
for line in text.splitlines():
    if line.lower().startswith("location:"):
        location = line.split(":", 1)[1].strip()
parsed = urlparse(location)
host = (parsed.hostname or "").lower().rstrip(".")
suffix = ".private.blob.vercel-storage.com"
label = host[: -len(suffix)] if host.endswith(suffix) else ""
path = parsed.path.lower()
query = parsed.query
ok = (
    parsed.scheme == "https"
    and not parsed.username
    and not parsed.password
    and bool(label)
    and "." not in label
    and all(c.isalnum() or c == "-" for c in label)
    and "/archive/" not in path
    and "/zipball/" not in path
    and "/tarball/" not in path
    and not path.endswith(".git")
    and "vercel-blob-signature=" in query
    and "vercel-blob-delegation=" in query
)
if not ok:
    raise SystemExit(1)
sys.stdout.write(location)
PY
    ) || {
        echo "Download link is invalid or expired."
        rm -f "${ARCHIVE}" "${HEADERS}"
        exit 1
    }
    rm -f "${ARCHIVE}" "${HEADERS}"
    unset HEADERS
    ARCHIVE=$(mktemp)
    ARCHIVE_CODE=$(curl -sS --max-time 180 -o "${ARCHIVE}" -w '%{http_code}' "${BLOB_URL}") || {
        echo "Download link is invalid or expired."
        rm -f "${ARCHIVE}"
        exit 1
    }
    unset BLOB_URL
elif [ "${ARCHIVE_CODE}" != "200" ]; then
    api_error "${ARCHIVE}"
    rm -f "${ARCHIVE}" "${HEADERS}"
    exit 1
else
    echo "Download link is invalid or expired."
    rm -f "${ARCHIVE}" "${HEADERS}"
    exit 1
fi
if [ "${ARCHIVE_CODE}" != "200" ]; then
    api_error "${ARCHIVE}"
    rm -f "${ARCHIVE}"
    exit 1
fi

unpack_release() {
    local archive="$1"
    local dest="$2"
    local tmp root preserve
    tmp=$(mktemp -d)
    tar -xzf "${archive}" -C "${tmp}"
    root="${tmp}"
    if [ ! -f "${tmp}/backend/main.py" ]; then
        local dirs=()
        local line
        while IFS= read -r line; do
            dirs+=("${line}")
        done < <(find "${tmp}" -mindepth 1 -maxdepth 1 -type d)
        if [ "${#dirs[@]}" -eq 1 ] && [ -f "${dirs[0]}/backend/main.py" ]; then
            root="${dirs[0]}"
        else
            echo "Release archive does not contain backend/main.py."
            rm -rf "${tmp}"
            exit 1
        fi
    fi
    preserve=$(mktemp -d)
    if [ -f "${dest}/config/settings.yaml" ]; then
        mkdir -p "${preserve}/config"
        cp -a "${dest}/config/settings.yaml" "${preserve}/config/settings.yaml"
    fi
    if [ -d "${dest}/data" ]; then
        mkdir -p "${preserve}/data"
        cp -a "${dest}/data/." "${preserve}/data/"
        rm -f "${preserve}/data/notable_aircraft.json" "${preserve}/data/aircraft_db.csv"
    fi
    mkdir -p "${dest}"
    cp -a "${root}/." "${dest}/"
    if [ -f "${preserve}/config/settings.yaml" ]; then
        mkdir -p "${dest}/config"
        cp -a "${preserve}/config/settings.yaml" "${dest}/config/settings.yaml"
    fi
    if [ -d "${preserve}/data" ]; then
        mkdir -p "${dest}/data"
        cp -a "${preserve}/data/." "${dest}/data/"
    fi
    rm -rf "${tmp}" "${preserve}"
}

unpack_release "${ARCHIVE}" "${INSTALL_DIR}"
rm -f "${ARCHIVE}"

if [ ! -f "${INSTALL_DIR}/frontend/dist/index.html" ]; then
    echo "The release archive has no frontend/dist. The desk cannot load."
    exit 1
fi

cd "${INSTALL_DIR}"

echo ""
echo -e "${YELLOW}Setting up Python environment...${NC}"

if [ ! -d "venv" ]; then
    python3 -m venv venv
fi
# shellcheck disable=SC1091
source venv/bin/activate
pip install -r backend/requirements.txt -q
echo -e "  Dependencies: ${GREEN}installed${NC}"

if [ ! -f "config/settings.yaml" ]; then
    echo ""
    echo -e "${YELLOW}Creating default configuration...${NC}"
    mkdir -p config
    cat > config/settings.yaml << EOF
# SkyBoss ATC — Settings
# Generated by installer on $(date)

default_airport: dca
refresh_interval_seconds: 5
data_source: auto

local_receiver:
  url: "${RECEIVER_URL}"
  blocked_sector_start: null
  blocked_sector_end: null

adsbx:
  api_key: ""

flightaware:
  api_key: ""

mapbox:
  access_token: ""

log_level: INFO
EOF
    echo -e "  Config: ${GREEN}config/settings.yaml created${NC}"
    echo -e "  ${CYAN}Open http://<your-ip>:${PORT} to enter the license key and pick your airport.${NC}"
fi

echo ""
echo -e "${YELLOW}Setting up auto-start service...${NC}"

SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

sudo tee "${SERVICE_FILE}" > /dev/null << EOF
[Unit]
Description=SkyBoss ATC Flight Tracker
After=network-online.target dump1090-fa.service
Wants=network-online.target

[Service]
Type=simple
User=${USER}
WorkingDirectory=${INSTALL_DIR}
ExecStart=${INSTALL_DIR}/venv/bin/python backend/main.py
Restart=always
RestartSec=10
Environment=PATH=${INSTALL_DIR}/venv/bin:/usr/local/bin:/usr/bin:/bin

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable "${SERVICE_NAME}" --quiet
sudo systemctl restart "${SERVICE_NAME}"

echo -e "  Service: ${GREEN}${SERVICE_NAME} enabled and started${NC}"

if iwconfig wlan0 2>/dev/null | grep -q "ESSID"; then
    echo ""
    echo -e "${YELLOW}WiFi detected — installing reliability watchdog...${NC}"
    if [ -f "${INSTALL_DIR}/scripts/setup-wifi-reliability.sh" ]; then
        bash "${INSTALL_DIR}/scripts/setup-wifi-reliability.sh" 2>/dev/null || true
        echo -e "  Watchdog: ${GREEN}installed (auto-recovers WiFi drops)${NC}"
    fi
fi

echo ""
echo -e "${GREEN}SkyBoss ATC installed successfully.${NC}"
echo ""

IP_ADDR=$(hostname -I | awk '{print $1}')
echo "  Open in your browser:"
echo -e "  ${GREEN}http://${IP_ADDR}:${PORT}${NC}"
echo "  Enter the same license key, then pick the airport."
echo ""
echo "  Useful commands:"
echo "    Status:   sudo systemctl status ${SERVICE_NAME}"
echo "    Logs:     journalctl -u ${SERVICE_NAME} -f"
echo "    Restart:  sudo systemctl restart ${SERVICE_NAME}"
echo "    Update:   curl -sSL https://skybossatc.com/install -o skyboss-install.sh"
echo "              SKYBOSS_LICENSE_KEY='your-key' bash skyboss-install.sh"
echo ""
