#!/usr/bin/env bash
# 在宿主机物理目录自动配置环境（无 Docker）
# 数据落盘：$ROOT/.runtime/{postgres,venv,logs,pids} 与 platform/data/uploads
# shellcheck disable=SC1091

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=common.sh
source "$SCRIPT_DIR/common.sh"

c_info "根目录(物理): $ROOT"
c_info "运行时目录:   $RUNTIME"
c_info "上传目录:     $UPLOAD_DIR"

need_pkgs=()
have_cmd curl || need_pkgs+=(curl)
have_cmd git || need_pkgs+=(git)
have_cmd go || need_pkgs+=(golang-go)
have_cmd python3 || need_pkgs+=(python3)
have_cmd pip3 || need_pkgs+=(python3-pip)
python3 -c "import venv" 2>/dev/null || need_pkgs+=(python3-venv)
have_cmd node || need_pkgs+=(nodejs)
have_cmd npm || need_pkgs+=(npm)
have_cmd psql || need_pkgs+=(postgresql-client)
have_cmd initdb || have_cmd pg_ctl || need_pkgs+=(postgresql)

install_pkgs() {
  local os
  os="$(detect_os)"
  c_info "安装系统包 (OS=$os): ${need_pkgs[*]}"
  case "$os" in
    ubuntu|debian|linuxmint|pop)
      sudo_run apt-get update -y
      local pkgs=()
      for p in "${need_pkgs[@]}"; do
        case "$p" in
          golang-go) pkgs+=(golang-go) ;;
          python3) pkgs+=(python3 python3-venv python3-dev) ;;
          python3-pip) pkgs+=(python3-pip) ;;
          python3-venv) pkgs+=(python3-venv) ;;
          nodejs) pkgs+=(nodejs) ;;
          npm) pkgs+=(npm) ;;
          postgresql) pkgs+=(postgresql postgresql-contrib) ;;
          postgresql-client) pkgs+=(postgresql-client) ;;
          *) pkgs+=("$p") ;;
        esac
      done
      sudo_run apt-get install -y "${pkgs[@]}"
      ;;
    fedora|rhel|centos|rocky|almalinux)
      local pkgs=()
      for p in "${need_pkgs[@]}"; do
        case "$p" in
          golang-go) pkgs+=(golang) ;;
          python3-pip) pkgs+=(python3-pip) ;;
          python3-venv) pkgs+=(python3) ;;
          postgresql) pkgs+=(postgresql-server postgresql) ;;
          postgresql-client) pkgs+=(postgresql) ;;
          *) pkgs+=("$p") ;;
        esac
      done
      if have_cmd dnf; then sudo_run dnf install -y "${pkgs[@]}"
      else sudo_run yum install -y "${pkgs[@]}"; fi
      ;;
    arch|manjaro)
      local pkgs=()
      for p in "${need_pkgs[@]}"; do
        case "$p" in
          golang-go) pkgs+=(go) ;;
          python3) pkgs+=(python) ;;
          python3-pip) pkgs+=(python-pip) ;;
          python3-venv) ;;
          postgresql-client) pkgs+=(postgresql) ;;
          *) pkgs+=("$p") ;;
        esac
      done
      sudo_run pacman -Sy --noconfirm "${pkgs[@]}"
      ;;
    *)
      c_err "未识别发行版 $os，请手动安装: go python3 node npm postgresql curl"
      return 1
      ;;
  esac
}

if ((${#need_pkgs[@]} > 0)); then
  install_pkgs
else
  c_ok "系统依赖已满足"
fi

missing=()
for c in go python3 curl; do have_cmd "$c" || missing+=("$c"); done
have_cmd node || have_cmd nodejs || missing+=("node")
have_cmd npm || missing+=("npm")
if ((${#missing[@]} > 0)); then
  c_err "仍缺少命令: ${missing[*]}"
  exit 1
fi
c_ok "$(go version)"

c_info "配置 Python venv → $VENV_DIR"
if [[ ! -d "$VENV_DIR" ]]; then
  python3 -m venv "$VENV_DIR"
fi
# shellcheck source=/dev/null
source "$VENV_DIR/bin/activate"
pip install -U pip wheel >/dev/null
pip install -r "$ROOT/ai-service/requirements.txt"
pip install -r "$ROOT/agent_sdk/requirements.txt"
c_ok "venv 依赖已安装"

c_info "安装前端依赖 → $ROOT/web/node_modules"
if [[ ! -d "$ROOT/web/node_modules" ]]; then
  (cd "$ROOT/web" && npm install)
else
  c_ok "web/node_modules 已存在"
fi

find_pg_bin() {
  local name="$1"
  if have_cmd "$name"; then command -v "$name"; return; fi
  local d
  for d in /usr/lib/postgresql/*/bin /usr/pgsql-*/bin; do
    if [[ -x "$d/$name" ]]; then echo "$d/$name"; return; fi
  done
  return 1
}

INITDB="$(find_pg_bin initdb || true)"
PG_CTL="$(find_pg_bin pg_ctl || true)"
PSQL="$(find_pg_bin psql || true)"

ensure_local_postgres() {
  if [[ -z "$INITDB" || -z "$PG_CTL" || -z "$PSQL" ]]; then
    c_warn "未找到 initdb/pg_ctl/psql，跳过本地库初始化（请自备 Postgres）"
    return 0
  fi

  # 已有可连库则复用
  if PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -c "SELECT 1" >/dev/null 2>&1; then
    c_ok "复用已有 Postgres $PG_USER@$PG_DB:$PG_PORT"
    PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" \
      -c "ALTER USER $PG_USER CREATEDB;" >/dev/null 2>&1 || true
    return 0
  fi

  mkdir -p "$PGDATA" "$RUNTIME/pg_sockets"
  if [[ ! -f "$PGDATA/PG_VERSION" ]]; then
    c_info "initdb → $PGDATA （物理目录）"
    "$INITDB" -D "$PGDATA" --auth=trust -U postgres
    {
      echo ""
      echo "listen_addresses = '127.0.0.1'"
      echo "port = $PG_PORT"
      echo "unix_socket_directories = '$RUNTIME/pg_sockets'"
    } >> "$PGDATA/postgresql.conf"
  fi

  if ! "$PG_CTL" -D "$PGDATA" status >/dev/null 2>&1; then
    c_info "启动本地 Postgres"
    "$PG_CTL" -D "$PGDATA" -l "$LOG_DIR/postgres.log" -o "-k $RUNTIME/pg_sockets" start
    sleep 1
  fi

  local sock="$RUNTIME/pg_sockets"
  "$PSQL" -h "$sock" -U postgres -d postgres -v ON_ERROR_STOP=1 <<SQL
DO \$\$
BEGIN
  IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '$PG_USER') THEN
    CREATE ROLE $PG_USER LOGIN PASSWORD '$PG_PASS' CREATEDB;
  ELSE
    ALTER ROLE $PG_USER WITH LOGIN PASSWORD '$PG_PASS' CREATEDB;
  END IF;
END
\$\$;
SELECT 'ok' FROM pg_database WHERE datname = '$PG_DB';
SQL
  if ! "$PSQL" -h "$sock" -U postgres -d postgres -tc "SELECT 1 FROM pg_database WHERE datname='$PG_DB'" | grep -q 1; then
    "$PSQL" -h "$sock" -U postgres -d postgres -c "CREATE DATABASE $PG_DB OWNER $PG_USER;"
  fi

  # 校验 TCP
  if ! PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -c "SELECT 1" >/dev/null 2>&1; then
    # 补充密码认证
    cat > "$PGDATA/pg_hba.conf" <<EOF
local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
EOF
    "$PG_CTL" -D "$PGDATA" reload || "$PG_CTL" -D "$PGDATA" restart -m fast
    sleep 1
  fi
  PGPASSWORD="$PG_PASS" "$PSQL" -h 127.0.0.1 -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -c "SELECT 1" >/dev/null
  c_ok "Postgres 就绪 (物理 data=$PGDATA)"
}

ensure_local_postgres

c_info "编译 platform / gateway"
(cd "$ROOT/platform" && go build -o platform .)
(cd "$ROOT/gateway" && go build -o gateway .)
c_ok "二进制已生成"

if [[ ! -f "$ROOT/ai-service/sample_inventory.xlsx" ]]; then
  (cd "$ROOT/ai-service" && "$VENV_DIR/bin/python" make_sample_excel.py) || true
fi

date -Iseconds > "$RUNTIME/setup.ok"
cat > "$RUNTIME/env.sh" <<EOF
# 由 setup-host.sh 生成 — 物理目录运行时
export AJZ_ROOT="$ROOT"
export AJZ_RUNTIME="$RUNTIME"
export PATH="$VENV_DIR/bin:\$PATH"
export PGHOST=127.0.0.1
export PGPORT=$PG_PORT
export PGUSER=$PG_USER
export PGPASSWORD=$PG_PASS
export PGDATABASE=$PG_DB
EOF

c_info "环境配置完成（无 Docker，全部落在物理目录）"
c_ok "下一步: ./start.sh"
