#!/usr/bin/env bash
set -euo pipefail
VERSION="${SCPANEL_VERSION:-1.4.1}"
APP=/opt/scpanel
CFG=/etc/scpanel
DATA=/var/lib/scpanel
VENV="$APP/venv"
echo "== SIKON Cpanel v$VERSION installer =="
[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(P[0-9]+)?$ ]] || { echo "Invalid panel version"; exit 1; }
apt-get update -y
apt-get install -y python3 python3-venv python3-pip ca-certificates openssl
install -d "$APP" "$CFG" "$DATA"
python3 -m venv "$VENV"
"$VENV/bin/pip" install --upgrade pip setuptools wheel
"$VENV/bin/pip" install -r "$APP/requirements.txt"
if [[ -n "${SCPANEL_ADMIN_PASSWORD:-}" ]]; then
  PW="$SCPANEL_ADMIN_PASSWORD"
elif [[ -f "$CFG/admin.env" ]]; then
  PW="$(sed -n 's/^SCPANEL_ADMIN_PASSWORD=//p' "$CFG/admin.env" | head -n1)"
  [[ -n "$PW" ]] || PW="$(openssl rand -base64 18 | tr -dc 'A-Za-z0-9@#%+=' | head -c 18)"
else
  PW="$(openssl rand -base64 18 | tr -dc 'A-Za-z0-9@#%+=' | head -c 18)"
fi
SECRET="${SCPANEL_SECRET_KEY:-$(if [[ -f "$CFG/admin.env" ]]; then sed -n 's/^SCPANEL_SECRET_KEY=//p' "$CFG/admin.env" | head -n1; fi)}"
[[ -n "$SECRET" ]] || SECRET="$(openssl rand -hex 32)"
printf 'SCPANEL_ADMIN_USER=scroot\nSCPANEL_ADMIN_PASSWORD=%s\nSCPANEL_VERSION=%s\nSCPANEL_SECRET_KEY=%s\n' "$PW" "$VERSION" "$SECRET" > "$CFG/admin.env"
chmod 0600 "$CFG/admin.env"
printf '%s\n' "$VERSION" > "$APP/RELEASE_VERSION"
chmod 0644 "$APP/RELEASE_VERSION"
python3 - "$CFG/config.json" "$VERSION" <<'PY'
import json,sys
p=sys.argv[1]; v=sys.argv[2]
o={"version":v,"os":{"name":"unknown","version":"unknown"},"mirror_url":"https://mirror.sikon.com.bd/scpanel/","ports":{"admin_http":2086,"admin_https":2087,"user_http":2082,"user_https":2083},"paths":{"app":"/opt/scpanel","config":"/etc/scpanel","data":"/var/lib/scpanel","tls":"/etc/scpanel/tls","webroot":"/home/scpanel/sites"},"timezone":"UTC","log_retention_days":30}
try:
    import platform
    o["os"]={"name":platform.system(),"version":platform.platform()}
except: pass
open(p,"w").write(json.dumps(o,separators=(",",":")))
PY
cat > /etc/systemd/system/scpanel-admin.service <<EOF
[Unit]
Description=SIKON Cpanel Admin HTTPS
After=network.target
[Service]
WorkingDirectory=$APP
EnvironmentFile=$CFG/admin.env
Environment=SCPANEL_VERSION=$VERSION
Environment=SCPANEL_SECRET_KEY=$SECRET
ExecStart=$VENV/bin/gunicorn --workers 1 --threads 8 --bind 0.0.0.0:2087 --certfile $CFG/server.crt --keyfile $CFG/server.key --access-logfile - --error-logfile - app.app:app
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/scpanel-user.service <<EOF
[Unit]
Description=SIKON Cpanel User HTTPS
After=network.target
[Service]
WorkingDirectory=$APP
EnvironmentFile=$CFG/admin.env
Environment=SCPANEL_VERSION=$VERSION
Environment=SCPANEL_SECRET_KEY=$SECRET
ExecStart=$VENV/bin/gunicorn --workers 1 --threads 8 --bind 0.0.0.0:2083 --certfile $CFG/server.crt --keyfile $CFG/server.key --access-logfile - --error-logfile - app.app:app
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

cat > /etc/systemd/system/scpanel-admin-http.service <<EOF
[Unit]
Description=SIKON Cpanel Admin HTTP Redirect
After=network.target
[Service]
ExecStart=/usr/bin/python3 $APP/scripts/redirect_http.py 2086 2087
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/scpanel-user-http.service <<EOF
[Unit]
Description=SIKON Cpanel User HTTP Redirect
After=network.target
[Service]
ExecStart=/usr/bin/python3 $APP/scripts/redirect_http.py 2082 2083
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
if [[ ! -f "$CFG/server.crt" ]]; then
  openssl req -x509 -nodes -newkey rsa:2048 -days 3650 -keyout "$CFG/server.key" -out "$CFG/server.crt" -subj "/CN=SCpanel" >/dev/null 2>&1
  chmod 600 "$CFG/server.key"
fi
ln -sf "$APP/scripts/scpanelctl" /usr/local/bin/scpanelctl
systemctl daemon-reload
# SCpanel SSL automatic renewal scheduler. It is safe when Certbot is not yet installed;
# the scheduled job exits cleanly until certificates are managed.
install -m 0755 "$APP/scripts/scpanel-ssl-renew" /usr/local/sbin/scpanel-ssl-renew
install -m 0755 "$APP/scripts/scpanel-certbot-deploy-hook" /usr/local/sbin/scpanel-certbot-deploy-hook
install -m 0644 "$APP/scripts/scpanel-ssl-renew.service" /etc/systemd/system/scpanel-ssl-renew.service
install -m 0644 "$APP/scripts/scpanel-ssl-renew.timer" /etc/systemd/system/scpanel-ssl-renew.timer
systemctl daemon-reload
systemctl enable --now scpanel-admin scpanel-user scpanel-admin-http scpanel-user-http scpanel-ssl-renew.timer
"$VENV/bin/python" - "$VERSION" <<'PY'
import urllib.request,ssl,json,sys,time,socket
expected=sys.argv[1]; ctx=ssl._create_unverified_context()
for port in (2087,2083):
    last=None
    for _ in range(45):
        try:
            u=f"https://127.0.0.1:{port}/api/version"; data=json.load(urllib.request.urlopen(u,context=ctx,timeout=3)); assert data["version"]==expected,data; break
        except Exception as exc: last=exc; time.sleep(1)
    else:
        import subprocess
        subprocess.run(["systemctl","--no-pager","--full","status",f"scpanel-admin" if port==2087 else f"scpanel-user"],check=False)
        raise SystemExit(f"SCpanel listener/API readiness failed on {port}: {last}")
print(f"SCpanel {expected} API smoke test: OK")
PY
"$VENV/bin/python" - <<'PYHEALTH'
import urllib.request,ssl,json
ctx=ssl._create_unverified_context()
data=json.load(urllib.request.urlopen("https://127.0.0.1:2087/api/health",context=ctx,timeout=10))
assert data["version"]==open("/opt/scpanel/RELEASE_VERSION").read().strip(), data
print("SCpanel health smoke test: OK")
PYHEALTH
"$VENV/bin/python" - <<'PYTASK'
import sys
sys.path.insert(0,"/opt/scpanel")
from app.task_engine import init as init_tasks
init_tasks()
from app.providers.service_engine import SPECS, catalog
assert "nginx" in SPECS and "php-fpm" in SPECS and "mariadb" in SPECS and "mysql" in SPECS
assert all("installed" in x and "running" in x and "enabled" in x and "dependencies" in x for x in catalog())
print("SCpanel P0 Task Engine + Provider smoke test: OK")
PYTASK
echo "============================================================"
echo "SIKON Cpanel v$VERSION installed successfully"
echo "Admin Username: scroot"
echo "Admin Password: $PW"
echo "Admin: https://$(hostname -I | xargs -n1 | head -n1):2087/admin/login"
echo "User : https://$(hostname -I | xargs -n1 | head -n1):2083/user/login"
echo "============================================================"
