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

if [[ ${EUID} -ne 0 ]]; then
  echo "Run this installer with sudo." >&2
  exit 1
fi

readonly SOURCE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
readonly PUBLIC_KEY_FILE="${1:-}"
readonly NGINX_LINK="/etc/nginx/sites-enabled/eusrr"
readonly UPSTREAM_FILE="/etc/nginx/conf.d/eusrr-active-upstreams.conf"

if [[ -z ${PUBLIC_KEY_FILE} || ! -f ${PUBLIC_KEY_FILE} ]]; then
  echo "Usage: $0 /path/to/gitea-runner.pub" >&2
  exit 2
fi
if ! id deploy >/dev/null 2>&1; then
  echo "The deploy system account does not exist." >&2
  exit 3
fi
if [[ ! -d ${SOURCE_DIR}/systemd ]]; then
  echo "Systemd templates are missing from ${SOURCE_DIR}." >&2
  exit 4
fi

exec 9>/run/lock/eusrr-deploy.lock
flock -n 9 || { echo "A deployment is running; retry bootstrap after it finishes." >&2; exit 3; }

read -r key_type key_body _ <"${PUBLIC_KEY_FILE}"
if [[ ${key_type} != "ssh-ed25519" || -z ${key_body:-} ]]; then
  echo "Expected an Ed25519 public key." >&2
  exit 5
fi

nginx_config="$(readlink -f "${NGINX_LINK}")"
nginx_backup="${nginx_config}.bak.blue-green.$(date -u +%Y%m%dT%H%M%SZ)"
cp -a "${nginx_config}" "${nginx_backup}"
upstream_existed=0
upstream_backup=""
if [[ -f ${UPSTREAM_FILE} ]]; then
  upstream_existed=1
  upstream_backup="${UPSTREAM_FILE}.bak.$(date -u +%Y%m%dT%H%M%SZ)"
  cp -a "${UPSTREAM_FILE}" "${upstream_backup}"
fi

install_complete=0
temporary_files=()
cleanup() {
  local status=$?
  for file in "${temporary_files[@]:-}"; do
    [[ -n ${file} ]] && rm -f "${file}"
  done
  if [[ ${install_complete} -eq 0 ]]; then
    cp -a "${nginx_backup}" "${nginx_config}"
    if [[ ${upstream_existed} -eq 1 ]]; then
      cp -a "${upstream_backup}" "${UPSTREAM_FILE}"
    else
      rm -f "${UPSTREAM_FILE}"
    fi
    nginx -t >/dev/null 2>&1 && systemctl reload nginx || true
  fi
  exit "${status}"
}
trap cleanup EXIT

install -o root -g root -m 0755 "${SOURCE_DIR}/eusrr-deploy" /usr/local/sbin/eusrr-deploy
install -o root -g root -m 0755 "${SOURCE_DIR}/eusrr-deploy-ssh" /usr/local/sbin/eusrr-deploy-ssh
install -d -o root -g root -m 0755 /usr/local/libexec /etc/systemd/journald.conf.d
install -o root -g root -m 0755 "${SOURCE_DIR}/eusrr-deploy-healthcheck" /usr/local/libexec/eusrr-deploy-healthcheck
install -o root -g root -m 0644 "${SOURCE_DIR}/logrotate.conf" /etc/logrotate.d/eusrr-deploy
install -o root -g root -m 0644 "${SOURCE_DIR}/journald.conf" /etc/systemd/journald.conf.d/60-eusrr-retention.conf
for unit in "${SOURCE_DIR}"/systemd/*.service; do
  install -o root -g root -m 0644 "${unit}" "/etc/systemd/system/$(basename "${unit}")"
done

install -d -o deploy -g eusrr -m 2775 /srv/eusrr-releases
install -d -o root -g root -m 0755 /srv/eusrr-slots
chmod 00755 /srv/eusrr-slots
install -d -o deploy -g www-data -m 0755 /srv/eusrr-shared /srv/eusrr-shared/next-static
if [[ -d /srv/eusrr/frontend/.next/static ]]; then
  rsync -a /srv/eusrr/frontend/.next/static/ /srv/eusrr-shared/next-static/
fi
chown -R deploy:www-data /srv/eusrr-shared
find /srv/eusrr-shared -type d -exec chmod 0755 {} +
find /srv/eusrr-shared -type f -exec chmod 0644 {} +

# Re-running bootstrap on an existing native slot must not point static files
# back at the legacy checkout while Nginx still serves the native slot.
if [[ ! -L /srv/eusrr-current ]]; then
  ln -sfn /srv/eusrr /srv/eusrr-current.new
  mv -Tf /srv/eusrr-current.new /srv/eusrr-current
fi

if [[ ! -f ${UPSTREAM_FILE} ]]; then
  cat >"${UPSTREAM_FILE}" <<'EOF'
upstream eusrr_backend {
    server 127.0.0.1:9000;
    keepalive 32;
}

upstream eusrr_frontend {
    server 127.0.0.1:3000;
    keepalive 32;
}
EOF
  chmod 0644 "${UPSTREAM_FILE}"
fi

NGINX_CONFIG="${nginx_config}" python3 <<'PY'
import os
import re
from pathlib import Path

path = Path(os.environ["NGINX_CONFIG"])
text = path.read_text(encoding="utf-8")

next_static = re.compile(
    r"^    location /_next/static/ \{\n.*?^    \}",
    flags=re.MULTILINE | re.DOTALL,
)
replacement = """    location /_next/static/ {
        alias /srv/eusrr-shared/next-static/;
        autoindex off;
        expires 365d;
        add_header Cache-Control \"public, immutable\";
    }"""
text, static_blocks = next_static.subn(replacement, text)
if static_blocks not in (0, 2):
    raise SystemExit(f"Expected zero or two Next.js static blocks, found {static_blocks}")

text = text.replace("proxy_pass http://127.0.0.1:9000;", "proxy_pass http://eusrr_backend;")
text = text.replace("proxy_pass http://127.0.0.1:3000;", "proxy_pass http://eusrr_frontend;")
text = text.replace(
    "alias /srv/eusrr/backend/staticfiles/;",
    "alias /srv/eusrr-current/backend/staticfiles/;",
)

required = (
    "proxy_pass http://eusrr_backend;",
    "proxy_pass http://eusrr_frontend;",
    "alias /srv/eusrr-shared/next-static/;",
    "alias /srv/eusrr-current/backend/staticfiles/;",
)
for marker in required:
    if marker not in text:
        raise SystemExit(f"Nginx transformation marker is missing: {marker}")
if "proxy_pass http://127.0.0.1:9000;" in text or "proxy_pass http://127.0.0.1:3000;" in text:
    raise SystemExit("Legacy direct upstreams remain in Nginx configuration")

path.write_text(text, encoding="utf-8")
PY

install -d -o root -g root -m 0755 /etc/eusrr/slots /var/lib/eusrr-deploy
[[ $(ssh-keygen -lf "${SOURCE_DIR}/gitea_known_hosts" | awk '{print $2}') == \
  'SHA256:341ON+FsVZMVMsduFUZjevfxjagbFG9yPeZ0edTVSOk' ]] || {
  echo 'Pinned Gitea host key fingerprint does not match.' >&2; exit 1;
}
install -o root -g root -m 0644 "${SOURCE_DIR}/gitea_known_hosts" /etc/eusrr/gitea_known_hosts
cat >/etc/eusrr/slots/blue.env <<'EOF'
BACKEND_PORT=9001
PORT=3001
HOSTNAME=127.0.0.1
EOF
cat >/etc/eusrr/slots/green.env <<'EOF'
BACKEND_PORT=9002
PORT=3002
HOSTNAME=127.0.0.1
EOF
chmod 0644 /etc/eusrr/slots/blue.env /etc/eusrr/slots/green.env
if [[ ! -f /var/lib/eusrr-deploy/active-slot ]]; then
  printf '%s\n' legacy >/var/lib/eusrr-deploy/active-slot
fi

install -d -o deploy -g deploy -m 0755 /var/log/celery
install -d -o deploy -g deploy -m 0700 /var/backups/eusrr/deploy
touch /var/log/eusrr-deploy.log
chown root:root /var/log/eusrr-deploy.log
chmod 0600 /var/log/eusrr-deploy.log

sudoers_tmp="$(mktemp)"
temporary_files+=("${sudoers_tmp}")
printf '%s\n' 'deploy ALL=(root) NOPASSWD: /usr/local/sbin/eusrr-deploy ^[0-9a-f]{40}$' >"${sudoers_tmp}"
chmod 0440 "${sudoers_tmp}"
visudo -cf "${sudoers_tmp}" >/dev/null
install -o root -g root -m 0440 "${sudoers_tmp}" /etc/sudoers.d/eusrr-deploy

deploy_home="$(getent passwd deploy | cut -d: -f6)"
install -d -o deploy -g deploy -m 0700 "${deploy_home}/.ssh"
authorized_keys="${deploy_home}/.ssh/authorized_keys"
touch "${authorized_keys}"
chown deploy:deploy "${authorized_keys}"
chmod 0600 "${authorized_keys}"
filtered_keys="$(mktemp)"
temporary_files+=("${filtered_keys}")
grep -v ' eusrr-gitea-runner$' "${authorized_keys}" >"${filtered_keys}" || true
printf '%s %s %s %s\n' \
  'command="/usr/local/sbin/eusrr-deploy-ssh",restrict' \
  "${key_type}" "${key_body}" 'eusrr-gitea-runner' >>"${filtered_keys}"
install -o deploy -g deploy -m 0600 "${filtered_keys}" "${authorized_keys}"

systemctl daemon-reload
nginx -t
systemctl reload nginx
/usr/local/sbin/eusrr-deploy --self-test

install_complete=1
echo "Restricted blue-green Gitea deployment installed successfully."
