/**
 * 启动前确保 DATABASE_URL 指向的 PostgreSQL 数据库已存在，不存在则创建。
 *
 * 背景：
 *   - `prisma db push` 会创建 schema（namespace）和表，但不会创建 PG database 本身。
 *   - K8s / compose 首次部署时，DBA / init 容器可能还没建好这张数据库；
 *     start-prod.sh 在这种情况下会卡在 `prisma db push` 报 "database does not exist"。
 *
 * 行为：
 *   - 解析 DATABASE_URL 拿到目标 dbname。
 *   - 连到同集群的 `postgres` 系统库，查 pg_database。
 *   - 不存在则 `CREATE DATABASE "<name>"`，已存在则直接返回。
 *
 * 失败语义：
 *   - 任何步骤异常（连接失败 / 权限不足 / SQL 报错）都直接 exit 1，让 start-prod.sh 终止。
 *     下游 push:db / 应用启动反正都会失败，越早暴露越好。
 *
 * 关闭开关：
 *   - 若部署侧确认 DB 由外部流程保证存在、不希望本步执行，
 *     设置环境变量 `SKIP_ENSURE_DATABASE=1` 即可跳过。
 */
const { Client } = require('pg');
const { URL } = require('url');

(async () => {
  if (process.env.SKIP_ENSURE_DATABASE === '1') {
    console.log('[ensure-database] SKIP_ENSURE_DATABASE=1，跳过');
    return;
  }

  const dbUrl = process.env.DATABASE_URL;
  if (!dbUrl) {
    console.error('[ensure-database] DATABASE_URL 为空');
    process.exit(1);
  }

  let parsed;
  try {
    parsed = new URL(dbUrl);
  } catch (e) {
    console.error('[ensure-database] DATABASE_URL 解析失败:', e.message);
    process.exit(1);
  }

  const dbName = decodeURIComponent(parsed.pathname.replace(/^\//, ''));
  if (!dbName) {
    console.error('[ensure-database] DATABASE_URL 中未指定数据库名');
    process.exit(1);
  }

  // 构造指向 `postgres` 系统库的连接串，并剔除 prisma 专属的 schema 参数
  const adminUrl = new URL(dbUrl);
  adminUrl.pathname = '/postgres';
  adminUrl.searchParams.delete('schema');

  const client = new Client({ connectionString: adminUrl.toString() });
  try {
    await client.connect();
    const r = await client.query(
      'SELECT 1 FROM pg_database WHERE datname = $1',
      [dbName],
    );
    if (r.rowCount > 0) {
      console.log(`[ensure-database] 数据库 "${dbName}" 已存在`);
      return;
    }

    // PostgreSQL 标识符引用：双引号包裹，内部双引号转义为两个双引号
    const escaped = `"${dbName.replace(/"/g, '""')}"`;
    console.log(`[ensure-database] 数据库 "${dbName}" 不存在，正在创建 ...`);
    await client.query(`CREATE DATABASE ${escaped}`);
    console.log(`[ensure-database] 数据库 "${dbName}" 创建成功`);
  } catch (e) {
    console.error('[ensure-database] 失败:', e.message);
    process.exit(1);
  } finally {
    await client.end().catch(() => {});
  }
})();
