#!/usr/bin/env bash
# scripts/lib/pg-bootstrap.sh
#
# 共享 helper：等待 PG 容器就绪 + 幂等安装 PG 扩展。
#
# 历史背景（issue #312）：deploy.sh / setup-worktree.sh / lib-test-db.sh 三处独立实现
# pg_isready 等待 + CREATE EXTENSION 循环，新增扩展要改三处。统一到这里后只改一处。
#
# 用法（source 后调用）：
#   source scripts/lib/pg-bootstrap.sh
#   wait_for_pg_container <container> <user> [db] [retries=30]
#   ensure_pg_extensions <container> <user> <db> [password] <ext...>
#     # password 传 "" 表示不注入 PGPASSWORD（容器内 trust auth 时可用）
#
# 日志通过 PG_BOOTSTRAP_LOG_PREFIX 控制前缀，方便 grep。

# guard against double-sourcing
if [[ -n "${_PG_BOOTSTRAP_LIB_LOADED:-}" ]]; then
    return 0 2>/dev/null || true
fi
_PG_BOOTSTRAP_LIB_LOADED=1

_pg_log() {
    local prefix="${PG_BOOTSTRAP_LOG_PREFIX:-pg-bootstrap}"
    echo "${prefix}: $*"
}

_pg_warn() {
    local prefix="${PG_BOOTSTRAP_LOG_PREFIX:-pg-bootstrap}"
    echo "${prefix}: $*" >&2
}

# wait_for_pg_container <container> <user> [db] [retries=30]
# 返回 0 = 就绪；返回 1 = 超时；容器不存在直接返回 2（caller 决定语义）
wait_for_pg_container() {
    local container="$1"
    local user="$2"
    local db="${3:-}"
    local retries="${4:-30}"

    if [[ -z "$container" || -z "$user" ]]; then
        _pg_warn "wait_for_pg_container: 缺参数（container=$container user=$user）"
        return 1
    fi

    if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -Fxq "$container"; then
        _pg_warn "容器 $container 未运行"
        return 2
    fi

    local args=(-U "$user")
    [[ -n "$db" ]] && args+=(-d "$db")

    local attempt=1
    while (( attempt <= retries )); do
        if docker exec "$container" pg_isready "${args[@]}" >/dev/null 2>&1; then
            _pg_log "PostgreSQL 已就绪（$container）"
            return 0
        fi
        sleep 1
        attempt=$((attempt + 1))
    done

    _pg_warn "PostgreSQL 在 ${retries}s 内未就绪（$container）"
    return 1
}

# ensure_pg_extensions <container> <user> <db> <password|""> <ext...>
# 对每个扩展执行 CREATE EXTENSION IF NOT EXISTS，幂等。
# 任一扩展失败返回非零（但继续尝试剩余扩展，方便 caller 看完整失败列表）。
ensure_pg_extensions() {
    local container="$1"
    local user="$2"
    local db="$3"
    local password="$4"
    shift 4

    if [[ -z "$container" || -z "$user" || -z "$db" || $# -eq 0 ]]; then
        _pg_warn "ensure_pg_extensions: 缺参数（需 container user db password ext...）"
        return 1
    fi

    local docker_env=()
    [[ -n "$password" ]] && docker_env=(-e "PGPASSWORD=$password")

    local rc=0
    local ext
    for ext in "$@"; do
        if docker exec "${docker_env[@]}" "$container" \
            psql -U "$user" -d "$db" -v ON_ERROR_STOP=1 \
            -tAc "CREATE EXTENSION IF NOT EXISTS ${ext};" >/dev/null 2>&1; then
            _pg_log "✅ 扩展已就绪: ${ext}"
        else
            _pg_warn "❌ 扩展安装失败: ${ext}（可能权限不足或 PG 未就绪）"
            rc=1
        fi
    done
    return $rc
}
