#!/usr/bin/env bash
set -euo pipefail

REPO_URL="https://git.lohmar.co.uk/lexton-it/NextWks.git"
BUILD_DIR="/tmp/nextwks-build"
TARGET_DIR="/opt/nextworkspace"
BACKUP_DIR="/opt/backup"
NETWORK_NAME="nextwks-net"
HEALTH_CHECK_RETRIES=15
HEALTH_CHECK_INTERVAL=3

usage() {
    echo "Usage: $0 [--install|--update|--destroy]"
    echo "  --install   First-time setup on a bare VM (prompts for config)"
    echo "  --update    Smart update: pull, build, copy, bounce containers"
    echo "  --destroy   Full greenfield redeploy (uses saved secrets)"
    exit 1
}

[ $# -eq 0 ] && usage
MODE="${1#--}"
case "$MODE" in install|update|destroy) ;; *) usage ;; esac

# MUST NOT run as root — podman must be rootless
if [ "$(id -u)" -eq 0 ]; then
    echo "ERROR: Do NOT run this script with sudo or as root."
    echo "  Run it as your normal user: ./nextwks.sh --$MODE"
    echo "  The script will prompt for sudo only where needed (apt, /opt/, iptables)."
    exit 1
fi

# Helper: run with sudo for operations that need root
maybe_sudo() {
    sudo "$@"
}

# --- Load existing env (if any), skip if unreadable ---
# Temporarily disable -u because .env may contain $ signs (bcrypt hashes)
set +u
if [ -r "$BACKUP_DIR/.env" ]; then
    set -a; source "$BACKUP_DIR/.env"; set +a
elif [ -r "$TARGET_DIR/.env" ]; then
    set -a; source "$TARGET_DIR/.env"; set +a
fi
set -u
DOMAIN="${DOMAIN:-nextwks.eu}"

echo "=== NextWorkspace ${MODE} ==="

# ============================================================
# 1. INSTALL MODE — first-time setup (only on bare VM)
# ============================================================
if [ "$MODE" = "install" ]; then
    if [ -f "$TARGET_DIR/nextworkspace" ]; then
        echo "================================================================="
        echo "  NextWorkspace is already installed at $TARGET_DIR"
        echo ""
        echo "  Use --update to rebuild and restart:"
        echo "    ./nextwks.sh --update"
        echo ""
        echo "  Use --destroy for a full greenfield redeploy:"
        echo "    ./nextwks.sh --destroy"
        echo "================================================================="
        exit 0
    fi
    echo "[*] Installing system dependencies..."
    maybe_sudo apt-get update -qq
    maybe_sudo apt-get install -y -qq git build-essential curl podman podman-compose iptables-persistent

    if ! command -v go &>/dev/null; then
        echo "[*] Installing Go..."
        GO_VERSION=$(curl -sL https://go.dev/VERSION?m=text)
        GO_URL="https://go.dev/dl/${GO_VERSION}.linux-amd64.tar.gz"
        curl -sL "$GO_URL" -o /tmp/go.tar.gz
        maybe_sudo rm -rf /usr/local/go
        maybe_sudo tar -C /usr/local -xzf /tmp/go.tar.gz
        rm /tmp/go.tar.gz
        maybe_sudo sh -c 'echo "export PATH=\$PATH:/usr/local/go/bin" > /etc/profile.d/go.sh'
        maybe_sudo chmod +x /etc/profile.d/go.sh
        export PATH=$PATH:/usr/local/go/bin
    fi

    # Enable user lingering — containers stay alive after logout
    maybe_sudo loginctl enable-linger "$USER" 2>/dev/null || true

    # Clean up any old rootful containers from a previous deploy
    echo "[*] Cleaning up old rootful containers (if any)..."
    maybe_sudo podman stop caddy authelia launcher 2>/dev/null || true
    maybe_sudo podman rm caddy authelia launcher 2>/dev/null || true
    maybe_sudo podman network rm "$NETWORK_NAME" 2>/dev/null || true

    echo ""
    echo "--- NextWorkspace Configuration ---"
    read -p "Domain [nextwks.eu]: " input; DOMAIN="${input:-$DOMAIN}"
    read -p "TLS email (Let's Encrypt): " TLS_EMAIL
    while [ -z "$TLS_EMAIL" ]; do read -p "TLS email (required): " TLS_EMAIL; done
    while echo "$TLS_EMAIL" | grep -qv '@'; do read -p "Invalid email: " TLS_EMAIL; done
    read -p "Admin username: " ADMIN_USERNAME
    while [ -z "$ADMIN_USERNAME" ]; do read -p "Admin username (required): " ADMIN_USERNAME; done
    # 24 chars, mixed case + numbers, no special chars (safe for .env)
    ADMIN_PASSWORD=$(openssl rand -base64 30 | tr -dc 'A-Za-z0-9')
    ADMIN_PASSWORD="${ADMIN_PASSWORD:0:24}"

    echo ""
    echo "========================================"
    echo "  Domain:         $DOMAIN"
    echo "  TLS email:      $TLS_EMAIL"
    echo "  Admin username: $ADMIN_USERNAME"
    echo "  Admin password: $ADMIN_PASSWORD"
    echo "  Save this password — it won't be shown again!"
    echo "========================================"
    echo ""

    read -p "SMTP host [smtp.openxchange.eu]: " SMTP_HOST; SMTP_HOST="${SMTP_HOST:-smtp.openxchange.eu}"
    read -p "SMTP port [587]: " SMTP_PORT; SMTP_PORT="${SMTP_PORT:-587}"
    read -p "SMTP user [post@nextwks.eu]: " SMTP_USER; SMTP_USER="${SMTP_USER:-post@nextwks.eu}"
    read -sp "SMTP password: " SMTP_PASS; echo ""
    [ -z "$SMTP_PASS" ] && echo "ERROR: SMTP password required" && exit 1

    read -p "IMAP host [imap.openxchange.eu]: " IMAP_HOST; IMAP_HOST="${IMAP_HOST:-imap.openxchange.eu}"
    read -p "IMAP port [993]: " IMAP_PORT; IMAP_PORT="${IMAP_PORT:-993}"

    # Persist config to backup vault (single-quote values to protect $ signs)
    maybe_sudo mkdir -p "$BACKUP_DIR"
    maybe_sudo sh -c "cat > '$BACKUP_DIR/.env' <<'ENVEOF'
# NextWorkspace Configuration — auto-generated by nextwks.sh --install
DOMAIN='$DOMAIN'
TLS_EMAIL='$TLS_EMAIL'
ADMIN_USERNAME='$ADMIN_USERNAME'
ADMIN_PASSWORD='$ADMIN_PASSWORD'
SMTP_HOST='$SMTP_HOST'
SMTP_PORT='$SMTP_PORT'
SMTP_USER='$SMTP_USER'
SMTP_PASS='$SMTP_PASS'
IMAP_HOST='$IMAP_HOST'
IMAP_PORT='$IMAP_PORT'
ENVEOF"
    maybe_sudo chmod 600 "$BACKUP_DIR/.env"
fi

# ============================================================
# 2. CLONE fresh (every mode — ensures latest code)
# ============================================================
echo "[*] Cloning repository..."
rm -rf "$BUILD_DIR"
git clone --depth 1 "$REPO_URL" "$BUILD_DIR"
cd "$BUILD_DIR"

# Save script to user's home for easy future access (--install only)
if [ "$MODE" = "install" ]; then
    cp "$BUILD_DIR/tools/nextwks.sh" "$HOME/nextwks.sh"
    chmod +x "$HOME/nextwks.sh"
    echo "[*] Saved to $HOME/nextwks.sh — use it for future updates"
fi

# ============================================================
# 3. FIREWALL SETUP (all modes)
# ============================================================
if [ "$MODE" = "install" ]; then
    echo "[*] Applying firewall and port redirects (80→8080, 443→8443)..."
    maybe_sudo bash "$BUILD_DIR/tools/firewall-routing.sh"
elif [ "$MODE" = "update" ] || [ "$MODE" = "destroy" ]; then
    # Lightweight: ensure redirects exist without flushing existing rules
    echo "[*] Ensuring port redirects (80→8080, 443→8443)..."
    maybe_sudo iptables -t nat -C PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 2>/dev/null || \
        maybe_sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
    maybe_sudo iptables -t nat -C PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443 2>/dev/null || \
        maybe_sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443
    maybe_sudo iptables -t nat -C OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-ports 8080 2>/dev/null || \
        maybe_sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-ports 8080
    maybe_sudo iptables -t nat -C OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to-ports 8443 2>/dev/null || \
        maybe_sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to-ports 8443
fi
# Persist across reboots (always)
if command -v netfilter-persistent &>/dev/null; then
    maybe_sudo netfilter-persistent save 2>/dev/null || true
else
    maybe_sudo mkdir -p /etc/iptables
    maybe_sudo sh -c 'iptables-save > /etc/iptables/rules.v4'
fi

# ============================================================
# 4. BUILD static binary
# ============================================================
echo "[*] Building static binary..."
export PATH=$PATH:/usr/local/go/bin
CGO_ENABLED=0 go build -o nextworkspace .

# ============================================================
# 5. STOP containers (all modes — binary is mounted, must stop before copy)
# ============================================================
echo "[*] Stopping containers..."
podman stop caddy authelia launcher 2>/dev/null || true
sleep 1

# ============================================================
# 6. CREATE target & backup directories (as root)
# ============================================================
maybe_sudo mkdir -p "$TARGET_DIR/config/caddy" "$TARGET_DIR/config/authelia" \
         "$TARGET_DIR/data/caddy" "$TARGET_DIR/data/authelia" \
         "$TARGET_DIR/compose" "$TARGET_DIR/www" \
         "$TARGET_DIR/config/nextworkspace" "$TARGET_DIR/logs" \
         "$BACKUP_DIR"

# ============================================================
# 7. TEARDOWN (destroy mode only — wipes target dir)
# ============================================================
if [ "$MODE" = "destroy" ]; then
    echo "[*] Full teardown..."
    # Stop rootless containers
    podman stop caddy authelia launcher 2>/dev/null || true
    podman rm caddy authelia launcher 2>/dev/null || true
    podman network rm -f "$NETWORK_NAME" 2>/dev/null || true
    # Wipe target
    maybe_sudo rm -rf "$TARGET_DIR"
    maybe_sudo mkdir -p "$TARGET_DIR/config/caddy" "$TARGET_DIR/config/authelia" \
             "$TARGET_DIR/data/caddy" "$TARGET_DIR/data/authelia" \
             "$TARGET_DIR/compose" "$TARGET_DIR/www" \
             "$TARGET_DIR/config/nextworkspace" "$TARGET_DIR/logs"
fi

# ============================================================
# 8. COPY artifacts to target (as root)
# ============================================================
echo "[*] Copying artifacts..."
maybe_sudo cp nextworkspace "$TARGET_DIR/nextworkspace"
maybe_sudo cp "$BUILD_DIR/VERSION" "$TARGET_DIR/VERSION"
if [ -d "$BUILD_DIR/config/www" ]; then
    maybe_sudo cp -r "$BUILD_DIR/config/www"/* "$TARGET_DIR/www/"
fi
if [ -d "$BUILD_DIR/lng" ]; then
    maybe_sudo rm -rf "$TARGET_DIR/lng"
    maybe_sudo cp -r "$BUILD_DIR/lng" "$TARGET_DIR/lng"
fi
if [ -d "$BUILD_DIR/config/nextworkspace" ]; then
    maybe_sudo cp -r "$BUILD_DIR/config/nextworkspace"/* "$TARGET_DIR/config/nextworkspace/"
fi
# Restore .env from backup
if [ -f "$BACKUP_DIR/.env" ]; then
    maybe_sudo cp "$BACKUP_DIR/.env" "$TARGET_DIR/.env"
    maybe_sudo chmod 644 "$TARGET_DIR/.env"
fi

# ============================================================
# 9. GENERATE config files with placeholder substitution
#    Write to /tmp first, then sudo cp to target
# ============================================================
GEN_DIR=$(mktemp -d)
trap "rm -rf '$GEN_DIR'" EXIT

echo "[*] Generating config files..."

# Caddyfile
sed -e "s|{DOMAIN}|$DOMAIN|g" -e "s|{TLS_EMAIL}|${TLS_EMAIL:-admin@$DOMAIN}|g" \
    "$BUILD_DIR/config/caddy/Caddyfile" > "$GEN_DIR/Caddyfile"

# Authelia config — preserve existing secrets if present
JWT_SECRET="${JWT_SECRET:-$(openssl rand -hex 32)}"
SESSION_SECRET="${SESSION_SECRET:-$(openssl rand -hex 32)}"
STORAGE_ENCRYPTION_KEY="${STORAGE_ENCRYPTION_KEY:-$(openssl rand -hex 32)}"
sed -e "s|{DOMAIN}|$DOMAIN|g" -e "s|{JWT_SECRET}|$JWT_SECRET|g" \
    -e "s|{SESSION_SECRET}|$SESSION_SECRET|g" \
    -e "s|{STORAGE_ENCRYPTION_KEY}|$STORAGE_ENCRYPTION_KEY|g" \
    -e "s|{SMTP_HOST}|${SMTP_HOST:-smtp.openxchange.eu}|g" \
    -e "s|{SMTP_PORT}|${SMTP_PORT:-587}|g" \
    -e "s|{SMTP_USER}|${SMTP_USER:-post@nextwks.eu}|g" \
    -e "s|{SMTP_PASS}|$SMTP_PASS|g" \
    "$BUILD_DIR/config/authelia/configuration.yml" > "$GEN_DIR/configuration.yml"

    # Users database — regenerate hash if ADMIN_PASSWORD is available
    if [ -n "${ADMIN_PASSWORD:-}" ]; then
        ADMIN_PASSWORD_HASH=$(cd "$BUILD_DIR" && go run ./tools/hash-password/ "$ADMIN_PASSWORD" 2>/dev/null || echo "$ADMIN_PASSWORD_HASH")
    fi
sed -e "s|{ADMIN_PASSWORD_HASH}|$ADMIN_PASSWORD_HASH|g" \
    -e "s|{TLS_EMAIL}|${TLS_EMAIL:-admin@$DOMAIN}|g" \
    "$BUILD_DIR/config/authelia/users_database.yml" > "$GEN_DIR/users_database.yml"

# Copy generated configs to target
maybe_sudo cp "$GEN_DIR/Caddyfile" "$TARGET_DIR/config/caddy/Caddyfile"
maybe_sudo cp "$GEN_DIR/configuration.yml" "$TARGET_DIR/config/authelia/configuration.yml"
maybe_sudo cp "$GEN_DIR/users_database.yml" "$TARGET_DIR/config/authelia/users_database.yml"

# Persist generated secrets so --destroy is idempotent
if [ -f "$BACKUP_DIR/.env" ]; then
    maybe_sudo sed -i "/^JWT_SECRET=/d; /^SESSION_SECRET=/d; /^STORAGE_ENCRYPTION_KEY=/d; /^ADMIN_PASSWORD_HASH=/d" "$BACKUP_DIR/.env" 2>/dev/null || true
fi
# Use pipe to avoid bash -c re-expanding $ signs (bcrypt hashes contain $2a$10$...)
echo "JWT_SECRET='$JWT_SECRET'" | maybe_sudo tee -a "$BACKUP_DIR/.env" >/dev/null
echo "SESSION_SECRET='$SESSION_SECRET'" | maybe_sudo tee -a "$BACKUP_DIR/.env" >/dev/null
echo "STORAGE_ENCRYPTION_KEY='$STORAGE_ENCRYPTION_KEY'" | maybe_sudo tee -a "$BACKUP_DIR/.env" >/dev/null
[ -n "$ADMIN_PASSWORD_HASH" ] && echo "ADMIN_PASSWORD_HASH='$ADMIN_PASSWORD_HASH'" | maybe_sudo tee -a "$BACKUP_DIR/.env" >/dev/null
maybe_sudo chmod 600 "$BACKUP_DIR/.env"

# ============================================================
# 10. FIX OWNERSHIP — all files in TARGET_DIR/BACKUP_DIR to user
# ============================================================
RUN_USER="${SUDO_USER:-${USER}}"
echo "[*] Setting file ownership to $RUN_USER..."
maybe_sudo chown -R "$RUN_USER:" "$TARGET_DIR" 2>/dev/null || true
maybe_sudo chown -R "$RUN_USER:" "$BACKUP_DIR" 2>/dev/null || true

# ============================================================
# 11. DEPLOY stack (rootless podman — no sudo!)
# ============================================================
echo "[*] Deploying containers on $NETWORK_NAME..."

podman network rm -f "$NETWORK_NAME" 2>/dev/null || true
podman network create --subnet 172.18.0.0/24 "$NETWORK_NAME"

# AUTHELIA_SECRET is SESSION_SECRET (Authelia session.secret)
AUTHELIA_SECRET="${SESSION_SECRET:-}"
if [ -z "$AUTHELIA_SECRET" ]; then
    AUTHELIA_SECRET=$(sed -n '/^session:/,/^[a-z]/p' "$TARGET_DIR/config/authelia/configuration.yml" \
        | grep 'secret:' | awk '{print $2}' 2>/dev/null || echo "")
fi

# Generate compose file with substituted secret
sed -e "s|{AUTHELIA_SECRET}|$AUTHELIA_SECRET|g" \
    "$BUILD_DIR/compose/stack.yaml" > "$GEN_DIR/stack.yaml"
cp "$GEN_DIR/stack.yaml" "$TARGET_DIR/compose/stack.yaml"

podman-compose -f "$TARGET_DIR/compose/stack.yaml" down 2>/dev/null || true
sleep 1
podman-compose -f "$TARGET_DIR/compose/stack.yaml" up -d 2>&1 || echo "[WARN] Stack deploy had issues"

# ============================================================
# 12. HEALTH CHECK
# ============================================================
echo "[*] Running health check..."
for i in $(seq 1 $HEALTH_CHECK_RETRIES); do
    HEALTH=$(podman exec launcher curl -sf http://127.0.0.1:9000/health 2>/dev/null || echo "")
    if [ "$HEALTH" = "OK" ]; then
        echo "[OK] NextWorkspace launcher is healthy"
        echo "[OK] https://$DOMAIN/"
        exit 0
    fi
    sleep $HEALTH_CHECK_INTERVAL
done

echo "[FAIL] Health check failed — launcher did not respond"
echo ""
echo "--- Container status ---"
podman ps -a --filter "name=caddy|authelia|launcher" 2>/dev/null || true
echo ""
echo "--- Launcher logs (last 20 lines) ---"
podman logs launcher --tail 20 2>/dev/null || echo "  (no logs)"
exit 1
