#!/bin/bash
################################################################################
# Script Name: version/3.0.4/UPDATE.sh
# Description: Apply version 3.0.4 migrations: install the terminal jail, take
#              the search engines' superuser logins and provision accounts,
#              let the WAF read site records again, and re-render OpenLiteSpeed
#              vhosts with per-site PHP handler names.
# Company: hitechcloud.org
# Copyright (c) hitechcloud.org
################################################################################

set -uo pipefail

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
ok()   { echo -e "[3.0.4] ${GREEN}✓${NC} $*"; }
warn() { echo -e "[3.0.4] ${YELLOW}!${NC} $*" >&2; }

[[ $EUID -eq 0 ]] || { echo "[3.0.4] This update must run as root." >&2; exit 1; }

CLI=/usr/local/hitechcloudcli
NATIVE=/etc/hitechcloud/native

# 1. The terminal jail: the web terminal and jailed SSH logins run inside a
#    mount namespace of the account's own from this release on. rbash, which
#    `bash`, `python3 -c` and `php -r` all escaped, stays only as a fallback.
if [ -f "$CLI/native/jail.sh" ]; then
    install -m 755 "$CLI/native/jail.sh" /usr/local/bin/hitechcloud-jail
    ok "Terminal jail installed (/usr/local/bin/hitechcloud-jail)"
    # Accounts whose SSH login is already on get the sudoers rule that lands
    # their login in the jail rather than in rbash.
    while IFS=: read -r name _ uid _ _ _ shell; do
        [ "$uid" -ge 1000 ] 2>/dev/null || continue
        [ "$shell" = /usr/local/bin/hitechcloud-shell ] || continue
        hitechcloudcli native-user shell "$name" on >/dev/null 2>&1 || true
    done < /etc/passwd
fi
if [ -f "$CLI/native/restricted-shell.sh" ]; then
    install -m 755 "$CLI/native/restricted-shell.sh" /usr/local/bin/hitechcloud-shell
fi

[ -f "$NATIVE/native.conf" ] || { ok "3.0.4 update steps completed (container architecture: nothing more to do)"; exit 0; }

# 2. The WAF service reads native.conf and the site records to find each
#    site's WebEngine, and 3.0.3's permission hardening left both readable by
#    root alone - so every firewalled site on Apache or OpenLiteSpeed was
#    proxied to nginx and answered 502. native-waf's ownership pass fixes it.
if [ -x "$CLI/native/waf.sh" ]; then
    bash "$CLI/native/waf.sh" status >/dev/null 2>&1 || true
    ok "Site records shared with the WAF service"
fi

# 3. OpenLiteSpeed: one external processor per site, not per PHP version.
#    Two sites on the same version used to share one entry, and the second
#    site's PHP requests went to the first site's PHP-FPM pool.
if [ -x "$CLI/native/vhost.sh" ] && [ -d "$NATIVE/openlitespeed/vhosts" ]; then
    for conf in "$NATIVE"/sites/*.conf; do
        [ -f "$conf" ] || continue
        domain=$(grep -E '^DOMAIN=' "$conf" | cut -d= -f2)
        [ -n "$domain" ] || continue
        [ -f "$NATIVE/openlitespeed/vhosts/$domain/vhost.conf" ] || continue
        hitechcloudcli native-vhost rebuild "$domain" >/dev/null 2>&1 \
            && ok "OpenLiteSpeed vhost re-rendered: $domain" \
            || warn "Could not rebuild $domain; run: hitechcloudcli native-vhost rebuild $domain"
    done
fi

# 4. OpenSearch / Elasticsearch: take the superuser login the package
#    generated and threw away, pin the ports, and give every account a login
#    of its own (the same thing native-cache does for Redis and Valkey).
if [ -x "$CLI/native/search.sh" ]; then
    if [ -d /etc/opensearch ] || [ -d /etc/elasticsearch ]; then
        bash "$CLI/native/search.sh" secure 2>&1 | sed 's/^/    /' || warn "native-search secure reported errors; run it by hand to see them"
        ok "Search engine logins provisioned"
    fi
fi

# 5. Ports the panel shows: Valkey and the search engines are read from the
#    engines' own configuration now, so nothing to migrate - but the cache
#    state file gains the Valkey port if native-cache has never written it.
if [ -x "$CLI/native/cache.sh" ] && [ ! -f "$NATIVE/cache.conf" ]; then
    bash "$CLI/native/cache.sh" status >/dev/null 2>&1 || true
fi

# 6. Sentinel was never installed on native servers (nothing called its
#    installer), so the Uptime page had nothing to read. Install it now.
if [ ! -x /usr/local/bin/sentinel ]; then
    for repo in /usr/local/hitechcloud /opt/hitechcloud "$(dirname "$(dirname "$(readlink -f "$0")")")/.."; do
        if [ -f "$repo/deploy/install-services.sh" ]; then
            REPO_DIR="$repo" bash "$repo/deploy/install-services.sh" sentinel >/dev/null 2>&1 \
                && ok "Sentinel health monitor installed" \
                || warn "Sentinel did not install; run: bash $repo/deploy/install-services.sh sentinel"
            break
        fi
    done
fi

# 7. pgAdmin was never installed either, so both panels' pgAdmin pages said
#    "not being served". Installed where PostgreSQL is.
if command -v psql >/dev/null 2>&1 && [ -x "$CLI/native/pgadmin.sh" ]; then
    if ! bash "$CLI/native/pgadmin.sh" status 2>/dev/null | grep -q "Service .*active"; then
        bash "$CLI/native/pgadmin.sh" install >/dev/null 2>&1 \
            && ok "pgAdmin installed" \
            || warn "pgAdmin did not install; run: hitechcloudcli native-pgadmin install"
    fi
fi

ok "3.0.4 update steps completed successfully"
exit 0
