#!/bin/bash
# deploy.sh - ai-disk-gateway のデプロイを一括で行う唯一のエントリポイント。
#
# 冪等に設計してある。何度実行しても同じ結果になる。
# 失敗時は Apache の vhost を元の状態へ戻して非ゼロ終了する。
#
# 使い方:
#   bash deploy.sh            通常のデプロイ
#   bash deploy.sh --skip-cert  証明書の取得と更新フックの設置を飛ばす
set -euo pipefail

REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$REPO_DIR/.deploy/lib.sh"

ENV_FILE="$REPO_DIR/.env"
ENV_EXAMPLE="$REPO_DIR/.env.example"
WEBROOT="$REPO_DIR/public"
LOCKFILE="/tmp/ai-disk-gateway-deploy.lock"

GATEWAY_PORT=3000
ADMIN_PORT=4000
PROXY_TIMEOUT=3600

SKIP_CERT=0
[[ "${1:-}" == "--skip-cert" ]] && SKIP_CERT=1

# ==============================================================
step "0. 排他ロックと前提チェック"
# ==============================================================
acquire_lock "$LOCKFILE"
preflight

# ==============================================================
step "1. .env の検証"
# ==============================================================
ensure_env "$ENV_FILE" "$ENV_EXAMPLE"

DOMAIN="$(env_get DOMAIN "$ENV_FILE")"
UPSTREAM_BASE_URL="$(env_get UPSTREAM_BASE_URL "$ENV_FILE")"
CERTBOT_EMAIL="$(env_get CERTBOT_EMAIL "$ENV_FILE")"
ADMIN_ALLOW_FROM="$(env_get ADMIN_ALLOW_FROM "$ENV_FILE")"

VHOST_NAME="002-${DOMAIN//./-}"
VHOST_PATH="/etc/apache2/sites-available/${VHOST_NAME}.conf"

if [[ -n "$ADMIN_ALLOW_FROM" ]]; then
    ADMIN_ACCESS="Require ip ${ADMIN_ALLOW_FROM}"
else
    ADMIN_ACCESS="Require all granted"
fi

log "対象ドメイン: $DOMAIN"
log "上流: $UPSTREAM_BASE_URL"
log "vhost: $VHOST_PATH"

# ==============================================================
step "2. Docker の導入"
# ==============================================================
install_docker
verify_upstream_reachable "$UPSTREAM_BASE_URL"

# ==============================================================
step "3. サブモジュールの取得"
# ==============================================================
sync_submodules

# ==============================================================
step "4. コンテナのビルドと起動"
# ==============================================================
mkdir -p "$WEBROOT/.well-known/acme-challenge"
chmod 755 "$REPO_DIR" "$WEBROOT"
compose_up
wait_healthy gateway 180
wait_healthy admin 120

# ==============================================================
step "5. Apache の設定"
# ==============================================================
enable_apache_modules
backup_vhost
trap 'rollback_vhost' ERR

TMP_VHOST="$(mktemp)"
trap 'rm -f "$TMP_VHOST"; rollback_vhost' ERR

if (( SKIP_CERT )) || cert_exists; then
    log "証明書は取得済みです。本番 vhost を適用します。"
    render_vhost "$REPO_DIR/.deploy/apache-vhost.conf.tpl" "$TMP_VHOST"
    install_vhost "$TMP_VHOST"
    apache_apply || die "本番 vhost の適用に失敗しました。"
else
    log "証明書が未取得です。3 段階で取得します。"

    log "  段階 1: 80 番のみの vhost を配置"
    render_vhost "$REPO_DIR/.deploy/apache-vhost-bootstrap.conf.tpl" "$TMP_VHOST"
    install_vhost "$TMP_VHOST"
    apache_apply || die "ブートストラップ vhost の適用に失敗しました。"

    log "  段階 2: 証明書の取得"
    obtain_certificate "$CERTBOT_EMAIL"

    log "  段階 3: 本番 vhost へ差し替え"
    render_vhost "$REPO_DIR/.deploy/apache-vhost.conf.tpl" "$TMP_VHOST"
    install_vhost "$TMP_VHOST"
    apache_apply || die "本番 vhost の適用に失敗しました。"
fi
rm -f "$TMP_VHOST"
trap 'rollback_vhost' ERR

if (( ! SKIP_CERT )); then
    install_renewal_hook "$REPO_DIR/.deploy/renewal-hook-reload-apache.sh"
fi

# ==============================================================
step "6. 定期ジョブの設定"
# ==============================================================
install_timers "$REPO_DIR/.deploy/systemd" "$REPO_DIR"

# ==============================================================
step "7. 疎通確認"
# ==============================================================
trap - ERR
if ! bash "$REPO_DIR/.deploy/healthcheck.sh"; then
    rollback_vhost
    die "疎通確認に失敗しました。ロールバックしました。"
fi

# ==============================================================
step "デプロイ完了"
# ==============================================================
ok "公開 URL:   https://${DOMAIN}/"
ok "管理画面:   https://${DOMAIN}/admin/"
echo
log "次にやること:"
log "  1. 管理画面にログインして最初の APIキーを発行する"
log "  2. 証明書の自動更新を検証する: sudo certbot renew --dry-run"
log "  3. ADMIN_ALLOW_FROM が空の場合は接続元を絞る"
