#!/bin/sh
set -e  # 任何命令失败时立即退出脚本

# 加载 .env 文件作为默认值（不覆盖已有环境变量）
if [ -f .env ]; then
  while IFS='=' read -r key value; do
    # 跳过空行和注释
    case "$key" in
      ''|\#*) continue ;;
    esac
    # 只在变量未设置时赋值
    eval "current_val=\${$key+x}"
    if [ -z "$current_val" ]; then
      export "$key=$value"
    fi
  done < .env
fi

# 检查环境变量是否为空
if [ -z "$DATABASE_URL" ]; then
    echo "Warning: DATABASE_URL is empty."
    exit 1
fi

echo "原始 DATABASE_URL: ${DATABASE_URL}"

# 确保目标数据库已存在；prisma db push 只建 schema/表，不会建 database 本身。
# 若部署环境已通过 DBA/init 流程保证 DB 存在，可设 SKIP_ENSURE_DATABASE=1 跳过。
node ensure-database.js || { echo "ensure-database 失败"; exit 1; }

# 如果存在DEPLOY_NAME环境变量，且变量值以feature或者bugfix开头，则执行数据库同步
# 检查 DEPLOY_NAME 是否以 feature/ 或 bugfix/ 或 hotfix/ 开头
DEPLOY_PREFIX_MATCH=0
if [ -n "$DEPLOY_NAME" ]; then
  case "$DEPLOY_NAME" in
    feature*|bugfix*|hotfix*)
      DEPLOY_PREFIX_MATCH=1
      ;;
  esac
fi

if [ "$DEPLOY_PREFIX_MATCH" -eq 1 ]; then
  # 将DATABASE_URL的schema设置为DEPLOY_NAME，需要把DEPLOY_NAME中的- 和 /替换为_
  SCHEMA_NAME=$(echo "$DEPLOY_NAME" | tr '-' '_' | tr '/' '_')
  
  echo "开始配置临时环境 schema: ${SCHEMA_NAME}"
  
  # 处理 DATABASE_URL 中的 schema 参数
  # 先移除可能存在的 schema 参数（包括空值的情况）
  # 使用 sed 移除 schema=xxx 或 schema= 参数
  DATABASE_URL=$(echo "$DATABASE_URL" | sed -E 's/[&?]schema=[^&?]*//g')
  # 清理 URL 末尾的 ? 或 &，以及重复的 & 和 ?& 组合
  DATABASE_URL=$(echo "$DATABASE_URL" | sed 's/[?&]$//' | sed 's/[?]&/?/g' | sed 's/&&\+/\&/g')
  
  # 确保 SCHEMA_NAME 不为空
  if [ -z "$SCHEMA_NAME" ]; then
    echo "错误: SCHEMA_NAME 为空"
    exit 1
  fi
  
  # prisma cli 需要使用这个环境变量来同步db表结构
  # 如果DATABASE_URL中已经包含了 ? ，则使用 & 拼接schema，否则使用 ? 拼接schema
  # https://www.prisma.io/docs/orm/more/development-environment/environment-variables
  case "$DATABASE_URL" in
    *\?*)
      DATABASE_URL="${DATABASE_URL}&schema=${SCHEMA_NAME}"
      ;;
    *)
      DATABASE_URL="${DATABASE_URL}?schema=${SCHEMA_NAME}"
      ;;
  esac

  echo "更新后的 DATABASE_URL: ${DATABASE_URL}"
  export DATABASE_URL="${DATABASE_URL}"

  yarn push:db || { echo "同步表结构失败"; exit 1; }

  # 设置迁移脚本的源和目标 schema
  # 源 schema 为 public（生产数据），目标 schema 为分支 schema
  export PG_SCHEMA="public"
  export PG_SCHEMA_TARGET="${SCHEMA_NAME}"

  node migrate-between-pg-schemas.js || { echo "迁移数据库失败"; exit 1; }

  # 临时环境每次启动都做一次 seed（幂等：upsert / skipDuplicates 风格，重复跑无害）
  echo "临时环境执行 seed ..."
  yarn seed || { echo "seed 失败"; exit 1; }
else
  echo "非临时环境，仅在权限表缺失或为空时同步表结构和数据"
  # 如果DATABASE_URL中已经包含了schema=xxx，则不添加，如果DATABASE_URL中没有schema=，则添加schema=public，如果DATABASE_URL中已经包含了schema=但没有具体值，则添加public
  case "$DATABASE_URL" in
    *"schema="*)
      # 情况 1 & 3: 已经包含 schema=
      case "$DATABASE_URL" in
        *"schema=")
          # 情况 3-A: 以 schema= 结尾（没有值）
          # 动作: 追加 public
          DATABASE_URL="${DATABASE_URL}public"
          ;;
        *"schema=&"*)
          # 情况 3-B: 包含 schema=&（在中间且没有值）
          # 动作: 使用 sed 替换为空缺的值填入 public
          DATABASE_URL=$(echo "$DATABASE_URL" | sed 's/schema=&/schema=public\&/')
          ;;
        *)
          # 情况 1: 包含 schema=xxx（已有具体值）
          # 动作: 不做任何修改
          ;;
      esac
      ;;
    *)
      # 情况 2: 完全没有 schema=
      # 动作: 判断连接符是 ? 还是 &
      case "$DATABASE_URL" in
        *"?"*)
          # URL 中已经有 ? (说明已有其他参数)
          DATABASE_URL="${DATABASE_URL}&schema=public"
          ;;
        *)
          # URL 中没有 ? (说明这是第一个参数)
          DATABASE_URL="${DATABASE_URL}?schema=public"
          ;;
      esac
      ;;
  esac

  echo "更新后的 DATABASE_URL: ${DATABASE_URL}"
  export DATABASE_URL="${DATABASE_URL}"

  # 通过查询权限表 t_role 判断是否需要初始化：
  #   - t_role 不存在（schema 全新）→ 抛错被 catch → 输出 "yes"
  #   - t_role 行数为 0（数据被清空）→ 输出 "yes"
  #   - 其它情况 → 输出 "no"
  # 任何意外异常（连接失败等）也保守地走初始化路径。
  NEEDS_INIT=$(node -e "const{PrismaClient}=require('@prisma/client');const p=new PrismaClient();p.\$queryRawUnsafe('SELECT COUNT(*)::int AS c FROM t_role').then(r=>{process.stdout.write(Number(r[0].c)>0?'no':'yes');return p.\$disconnect();}).catch(()=>{process.stdout.write('yes');return p.\$disconnect().catch(()=>{});});" 2>/dev/null || echo "yes")

  if [ "$NEEDS_INIT" != "no" ]; then
    echo "权限表缺失或无数据（NEEDS_INIT=${NEEDS_INIT}），执行 push:db + seed ..."
    yarn push:db || { echo "同步表结构失败"; exit 1; }
    yarn seed    || { echo "seed 失败"; exit 1; }
  else
    echo "权限数据已就绪，跳过 push:db 与 seed"
  fi
fi

# 启动应用（在同一个 shell 会话中，确保环境变量可用）
# 使用 exec 替换当前进程，这样环境变量可以正确传递
exec node dist/src/main