#!/bin/bash
# /opt/togen/update.sh
# Pulls latest Togen code from GitHub and hot-deploys it.
# Runs as manager (gunicorn user), triggered by the Togen Admin UI.

set -euo pipefail

LOG=/var/log/togen-update.log
REPO_DIR=/opt/togen/repo
DEPLOY_DIR=/var/www/html/togen
REPO_URL=git@github.com:andycrawford/Togen.git

# The git step authenticates to GitHub with manager's key (~/.ssh/togen_deploy).
# root has no GitHub key, so a sudo/root invocation fails with
# "Permission denied (publickey)" (DVI-1049). Always run as manager.
DEPLOY_USER=manager
if [ "$(id -un)" != "$DEPLOY_USER" ]; then
    echo "update.sh: re-executing as $DEPLOY_USER (was $(id -un))" >&2
    exec sudo -u "$DEPLOY_USER" -H "$0" "$@"
fi

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"
}

log "=== Togen update started ==="

# Ensure Liberation Sans font is installed (required by create_carrier_sheet in qr_merge.py).
# The check is fast (dpkg -l); install only runs once.
if ! dpkg -l fonts-liberation >/dev/null 2>&1; then
    log "Installing fonts-liberation (required for carrier sheet text rendering)"
    sudo apt-get install -y fonts-liberation 2>>"$LOG" \
        || log "WARNING: fonts-liberation install failed — run: sudo apt-get install -y fonts-liberation"
fi

# Install OCR system packages required by OCRmyPDF (tesseract engine + PDF tools).
for pkg in tesseract-ocr ghostscript qpdf; do
    if ! dpkg -l "$pkg" >/dev/null 2>&1; then
        log "Installing $pkg (required by ocrmypdf)"
        sudo apt-get install -y "$pkg" 2>>"$LOG" \
            || log "WARNING: $pkg install failed — run: sudo apt-get install -y $pkg"
    fi
done

# Clone on first run; pull thereafter
if [ -d "$REPO_DIR/.git" ]; then
    log "Pulling latest from main branch"
    git -C "$REPO_DIR" fetch --quiet origin
    git -C "$REPO_DIR" reset --hard origin/main
else
    log "Cloning repository for the first time"
    mkdir -p "$REPO_DIR"
    git clone --branch main --depth 1 "$REPO_URL" "$REPO_DIR"
fi

COMMIT_HASH=$(git -C "$REPO_DIR" rev-parse HEAD)
log "Checked out commit: $COMMIT_HASH"

# Install/update Python packages from requirements.txt into the qr-web venv.
VENV_PIP=/var/www/html/qr/venv/bin/pip
if [ -f "$REPO_DIR/requirements.txt" ] && [ -x "$VENV_PIP" ]; then
    log "Installing Python packages from requirements.txt into venv"
    "$VENV_PIP" install -q -r "$REPO_DIR/requirements.txt" 2>>"$LOG" \
        || log "WARNING: pip install failed — run: $VENV_PIP install -r $REPO_DIR/requirements.txt"
else
    log "WARNING: venv pip ($VENV_PIP) or requirements.txt not found — skipping pip install"
fi

# Copy app files
log "Copying app.py, wsgi.py, ocr_engine.py and assistant.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/app.py"        "$DEPLOY_DIR/app.py"
cp "$REPO_DIR/togen/wsgi.py"       "$DEPLOY_DIR/wsgi.py"
cp "$REPO_DIR/togen/ocr_engine.py" "$DEPLOY_DIR/ocr_engine.py"
cp "$REPO_DIR/togen/assistant.py"  "$DEPLOY_DIR/assistant.py"

# Deploy branding SVG assets (corporate logo + light/dark backgrounds)
for svg in corporate_logo.svg corporate_bg_light.svg corporate_bg_dark.svg logo-black.svg; do
    if [ -f "$REPO_DIR/togen/$svg" ]; then
        log "Copying $svg to $DEPLOY_DIR"
        cp "$REPO_DIR/togen/$svg" "$DEPLOY_DIR/$svg"
    fi
done

# Deploy document viewer
DOCVIEWER_DIR=/var/www/html/docviewer
if [ -d "$REPO_DIR/docviewer" ]; then
    log "Deploying document viewer to $DOCVIEWER_DIR"
    cp "$REPO_DIR/docviewer/index.html"    "$DOCVIEWER_DIR/index.html"
    cp "$REPO_DIR/docviewer/.htaccess"     "$DOCVIEWER_DIR/.htaccess"
    cp "$REPO_DIR/docviewer/logo-color.svg" "$DOCVIEWER_DIR/logo-color.svg"
    cp "$REPO_DIR/docviewer/logo-white.svg" "$DOCVIEWER_DIR/logo-white.svg"
fi

# Write VERSION file
# Build the JSON with python3 (json.dumps escapes quotes/backslashes in the
# commit subject) — a raw git --format template breaks on messages containing
# double quotes, which the /togen-admin/version reader then fails to parse.
log "Writing VERSION file"
VER_HASH=$(git -C "$REPO_DIR" log -1 --format='%H')
VER_DATE=$(git -C "$REPO_DIR" log -1 --format='%aI')
VER_MSG=$(git -C "$REPO_DIR" log -1 --format='%s')
python3 -c 'import json,sys; print(json.dumps({"hash":sys.argv[1],"date":sys.argv[2],"message":sys.argv[3]}))' \
    "$VER_HASH" "$VER_DATE" "$VER_MSG" > "$DEPLOY_DIR/VERSION"
log "VERSION: $(cat "$DEPLOY_DIR/VERSION")"

# Deploy qr-merge library (qr_merge.py + blank template) to /opt/qr-merge/
QR_MERGE_DIR=/opt/qr-merge
if [ -d "$QR_MERGE_DIR" ]; then
    log "Deploying qr_merge.py and CarrierQR blank.pdf to $QR_MERGE_DIR"
    cp "$REPO_DIR/qr-merge/qr_merge.py"         "$QR_MERGE_DIR/qr_merge.py"
    cp "$REPO_DIR/qr-merge/CarrierQR blank.pdf"  "$QR_MERGE_DIR/CarrierQR blank.pdf"
    cp "$REPO_DIR/qr-merge/folder_watcher.py"    "$QR_MERGE_DIR/folder_watcher.py"
    log "Restarting qr-watcher.service"
    sudo systemctl restart qr-watcher.service
else
    log "WARNING: $QR_MERGE_DIR not found — skipping qr-merge deploy"
fi

# Deploy notification scheduler
log "Deploying notifications.py and notification_scheduler.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/notifications.py"          "$DEPLOY_DIR/notifications.py"
cp "$REPO_DIR/togen/notification_scheduler.py" "$DEPLOY_DIR/notification_scheduler.py"

log "Installing/updating notification-scheduler systemd units"
sudo cp "$REPO_DIR/services/notification-scheduler.service" \
    /etc/systemd/system/notification-scheduler.service
sudo cp "$REPO_DIR/services/notification-scheduler.timer" \
    /etc/systemd/system/notification-scheduler.timer
sudo systemctl daemon-reload
sudo systemctl enable notification-scheduler.timer
log "Restarting notification-scheduler.timer"
sudo systemctl restart notification-scheduler.timer

# Deploy SCADA report scheduler and store
log "Deploying scada_store.py, scada_report.py, scada_report_approvals.py and scada_report_scheduler.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/scada_store.py"             "$DEPLOY_DIR/scada_store.py"
cp "$REPO_DIR/togen/scada_report.py"            "$DEPLOY_DIR/scada_report.py"
cp "$REPO_DIR/togen/scada_report_approvals.py"  "$DEPLOY_DIR/scada_report_approvals.py"
cp "$REPO_DIR/togen/scada_report_scheduler.py"  "$DEPLOY_DIR/scada_report_scheduler.py"

# Deploy ThingPark LoRaWAN telemetry store (separate module; app.py imports it)
log "Deploying thingpark_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/thingpark_store.py" "$DEPLOY_DIR/thingpark_store.py"

# Deploy asset inventory store (DVI-1185; separate module; app.py imports it)
log "Deploying assets_store.py and asset_photo_extract.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/assets_store.py" "$DEPLOY_DIR/assets_store.py"
cp "$REPO_DIR/togen/asset_photo_extract.py" "$DEPLOY_DIR/asset_photo_extract.py"

# Deploy Idencia cache/snapshot store (DVI-1226; separate module; app.py imports it)
log "Deploying idencia_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/idencia_store.py" "$DEPLOY_DIR/idencia_store.py"

# Deploy Power BI cache/snapshot store (DVI-1243; separate module; app.py imports it)
log "Deploying powerbi_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/powerbi_store.py" "$DEPLOY_DIR/powerbi_store.py"

# Deploy NetSuite cache/snapshot store (DVI-1462; separate module; app.py imports it)
log "Deploying netsuite_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/netsuite_store.py" "$DEPLOY_DIR/netsuite_store.py"

# Deploy Paychex telemetry store (DVI-1462 P2; separate module; app.py imports it)
log "Deploying paychex_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/paychex_store.py" "$DEPLOY_DIR/paychex_store.py"

# Deploy Report Builder template store (DVI-1255; separate module; app.py imports it)
log "Deploying reports_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/reports_store.py" "$DEPLOY_DIR/reports_store.py"

# Deploy QC store (DVI-1326; separate module; app.py imports it)
log "Deploying qc_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/qc_store.py" "$DEPLOY_DIR/qc_store.py"

log "Deploying logistics_store.py to $DEPLOY_DIR"
cp "$REPO_DIR/togen/logistics_store.py" "$DEPLOY_DIR/logistics_store.py"

log "Installing/updating scada-report-scheduler systemd units"
sudo cp "$REPO_DIR/services/scada-report-scheduler.service" \
    /etc/systemd/system/scada-report-scheduler.service
sudo cp "$REPO_DIR/services/scada-report-scheduler.timer" \
    /etc/systemd/system/scada-report-scheduler.timer
sudo systemctl daemon-reload
sudo systemctl enable scada-report-scheduler.timer
log "Restarting scada-report-scheduler.timer"
sudo systemctl restart scada-report-scheduler.timer

# Also deploy qr_merge.py to /var/www/html/qr/ — togen/wsgi.py adds this directory
# to sys.path, so this copy is the one the Togen web service actually imports.
QR_WEB_DIR=/var/www/html/qr
if [ -f "$QR_WEB_DIR/qr_merge.py" ]; then
    log "Deploying qr_merge.py to $QR_WEB_DIR (used by Togen)"
    cp "$REPO_DIR/qr-merge/qr_merge.py"         "$QR_WEB_DIR/qr_merge.py"
    cp "$REPO_DIR/qr-merge/CarrierQR blank.pdf"  "$QR_WEB_DIR/CarrierQR blank.pdf"
else
    log "WARNING: $QR_WEB_DIR/qr_merge.py not found — skipping Togen qr_merge deploy"
fi

# Deploy public_files/ to /var/www/html/docviewer/files/ (no-auth static files)
# docs.icastinc.com DocumentRoot is /var/www/html/docviewer — files go there
PUBLIC_FILES_DIR=/var/www/html/docviewer/files
if [ -d "$REPO_DIR/public_files" ] && [ "$(ls -A "$REPO_DIR/public_files" 2>/dev/null)" ]; then
    log "Deploying public_files to $PUBLIC_FILES_DIR"
    mkdir -p "$PUBLIC_FILES_DIR"
    cp "$REPO_DIR/public_files/"* "$PUBLIC_FILES_DIR/"
    log "Public files deployed: $(ls "$REPO_DIR/public_files" | tr '\n' ' ')"
else
    log "No public_files to deploy (directory empty or missing)"
fi

# Deploy server-side scripts (e.g. add_fqdn_cert.sh used by the FQDN issuance job)
SCRIPTS_DEST="$DEPLOY_DIR/scripts"
if [ -d "$REPO_DIR/scripts" ]; then
    log "Deploying scripts/ to $SCRIPTS_DEST"
    mkdir -p "$SCRIPTS_DEST"
    cp "$REPO_DIR/scripts/"*.sh "$SCRIPTS_DEST/" 2>/dev/null || true
    chmod +x "$SCRIPTS_DEST/"*.sh 2>/dev/null || true
fi

# Deploy signage kiosk agent source files (DVI-1210) -- GET /signage/install.sh
# assembles the served bootstrap installer from these at request time
# (SIGNAGE_AGENT_DIR in app.py), so they must live next to app.py, not just in
# the repo checkout.
SIGNAGE_AGENT_DEST="$DEPLOY_DIR/signage_agent"
if [ -d "$REPO_DIR/togen/signage_agent" ]; then
    log "Deploying togen/signage_agent/ to $SIGNAGE_AGENT_DEST"
    mkdir -p "$SIGNAGE_AGENT_DEST"
    cp "$REPO_DIR/togen/signage_agent/"* "$SIGNAGE_AGENT_DEST/"
    chmod +x "$SIGNAGE_AGENT_DEST/"*.sh "$SIGNAGE_AGENT_DEST/xsession" 2>/dev/null || true
fi

# Deploy Windows display agent bundle dir (DVI-1227) — app.py serves
# GET /enroll/display-agent.zip from DISPLAY_AGENT_WIN_DIR next to app.py.
# The built togen-display-agent.zip lands in this repo dir once the Windows
# build (build_agent.ps1, P3) runs; until then the route 404s with guidance.
DISPLAY_AGENT_WIN_DEST="$DEPLOY_DIR/display_agent_win"
if [ -d "$REPO_DIR/togen/display_agent_win" ]; then
    log "Deploying togen/display_agent_win/ to $DISPLAY_AGENT_WIN_DEST"
    mkdir -p "$DISPLAY_AGENT_WIN_DEST"
    cp -R "$REPO_DIR/togen/display_agent_win/"* "$DISPLAY_AGENT_WIN_DEST/"
fi

# Restart services — togen-worker runs the schedulers/collector from the same
# code, so skipping it leaves stale code running (DVI-1095: collector silently
# ran pre-deploy code for 5 days).
log "Restarting qr-web.service"
sudo systemctl restart qr-web.service
log "Restarting togen-worker.service"
sudo systemctl restart togen-worker.service

log "=== Togen update complete ==="
