"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var import_client = require("@prisma/pg/client");
var fs = __toESM(require("fs/promises"));
var import_promises = require("fs/promises");
var path = __toESM(require("path"));
var fsSync = __toESM(require("fs"));
var dotenv = __toESM(require("dotenv"));
const args = process.argv.slice(2);
const get = (flag) => {
  const i = args.findIndex((a2) => a2 === `--${flag}` || a2.startsWith(`--${flag}=`));
  if (i === -1) return null;
  const a = args[i];
  const eq = a.indexOf("=");
  return eq > -1 ? a.slice(eq + 1) : null;
};
const explicitEnv = get("env") || process.env.DOTENV_CONFIG_PATH || null;
const guessedEnv = process.env.ENVIRONMENT || process.env.NODE_ENV || "development";
const CWD = process.cwd();
const candidates = explicitEnv ? [path.resolve(explicitEnv)] : [
  // root
  path.join(CWD, `.env.${guessedEnv}`),
  path.join(CWD, `.env.local`),
  path.join(CWD, `.env`),
  // prisma/
  path.join(CWD, "prisma", `.env.${guessedEnv}`),
  path.join(CWD, "prisma", `.env`),
  // prisma/pg/my_scripts/ (just in case)
  path.join(CWD, "prisma", "pg", "my_scripts", `.env.${guessedEnv}`),
  path.join(CWD, "prisma", "pg", "my_scripts", `.env`)
];
const envPath = candidates.find((p) => fsSync.existsSync(p));
if (envPath) {
  dotenv.config({ path: envPath });
  console.log(`[env] Loaded: ${envPath}`);
} else {
  console.warn(`[env] No .env found. Checked: ${candidates.join(" , ")}`);
}
if (!process.env.DATABASE_URL) {
  console.error(
    "[env] DATABASE_URL is not set. Add it to your env file or pass --env=PATH.\nExample:\nDATABASE_URL=postgresql://postgres:postgres@localhost:5432/lcp_framework"
  );
  process.exit(1);
}
function splitPostgresStatements(sql) {
  const out = [];
  let buf = "";
  let i = 0;
  let inSingle = false;
  let inDouble = false;
  let inLineComment = false;
  let inBlockComment = false;
  let dollarTag = null;
  const isIdent = (c) => /[A-Za-z0-9_]/.test(c);
  while (i < sql.length) {
    const ch = sql[i];
    const nxt = i + 1 < sql.length ? sql[i + 1] : "";
    if (inLineComment) {
      buf += ch;
      if (ch === "\n") inLineComment = false;
      i++;
      continue;
    }
    if (inBlockComment) {
      buf += ch;
      if (ch === "*" && nxt === "/") {
        buf += nxt;
        i += 2;
        inBlockComment = false;
        continue;
      }
      i++;
      continue;
    }
    if (dollarTag) {
      buf += ch;
      if (ch === "$") {
        const tagLen = dollarTag.length;
        const start = i - tagLen + 1;
        if (start >= 0 && sql.slice(start, i + 1) === dollarTag) {
          dollarTag = null;
        }
      }
      i++;
      continue;
    }
    if (inSingle) {
      buf += ch;
      if (ch === "'" && nxt === "'") {
        buf += nxt;
        i += 2;
        continue;
      }
      if (ch === "'") inSingle = false;
      i++;
      continue;
    }
    if (inDouble) {
      buf += ch;
      if (ch === '"' && nxt === '"') {
        buf += nxt;
        i += 2;
        continue;
      }
      if (ch === '"') inDouble = false;
      i++;
      continue;
    }
    if (ch === "-" && nxt === "-") {
      buf += ch + nxt;
      i += 2;
      inLineComment = true;
      continue;
    }
    if (ch === "/" && nxt === "*") {
      buf += ch + nxt;
      i += 2;
      inBlockComment = true;
      continue;
    }
    if (ch === "'") {
      buf += ch;
      inSingle = true;
      i++;
      continue;
    }
    if (ch === '"') {
      buf += ch;
      inDouble = true;
      i++;
      continue;
    }
    if (ch === "$") {
      let j = i + 1;
      while (j < sql.length && isIdent(sql[j])) j++;
      if (j < sql.length && sql[j] === "$") {
        const tag = sql.slice(i, j + 1);
        dollarTag = tag;
        buf += tag;
        i = j + 1;
        continue;
      }
      buf += ch;
      i++;
      continue;
    }
    if (ch === ";") {
      const stmt = buf.trim();
      if (stmt.length) out.push(stmt + ";");
      buf = "";
      i++;
      continue;
    }
    buf += ch;
    i++;
  }
  const tail = buf.trim();
  if (tail.length) out.push(tail);
  return out.filter((s) => /\S/.test(s));
}
function parseArgs() {
  const args2 = process.argv.slice(2);
  const get2 = (flag) => {
    const i = args2.findIndex((a2) => a2 === `--${flag}` || a2.startsWith(`--${flag}=`));
    if (i === -1) return null;
    const a = args2[i];
    const eq = a.indexOf("=");
    return eq > -1 ? a.slice(eq + 1) : null;
  };
  console.log(get2("dir"));
  const dir = get2("dir") || path.join(process.cwd(), "prisma", "pg", "my_scripts", "db-run", "common");
  const parsePatterns = (s) => (s || "").split(",").map((x) => x.trim()).filter(Boolean);
  const only = parsePatterns(get2("only"));
  const except = parsePatterns(get2("except"));
  const singleTx = args2.includes("--single-tx");
  const dryRun = args2.includes("--dry-run");
  return { dir, only, except, singleTx, dryRun };
}
function wildcardToRegex(pat) {
  const esc = pat.replace(/[-/\\^$+.,()|[\]{}]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
  return new RegExp(`^${esc}$`, "i");
}
function matchAny(name, patterns) {
  if (!patterns.length) return false;
  return patterns.some((p) => wildcardToRegex(p).test(name));
}
function containsPsqlMeta(sql) {
  return sql.split(/\r?\n/).some((line) => /^\s*\\[a-z]/i.test(line));
}
async function listSqlFiles(baseDir) {
  const entries = await fs.readdir(baseDir);
  const sqls = [];
  for (const name of entries) {
    if (!name.toLowerCase().endsWith(".sql")) continue;
    const full = path.join(baseDir, name);
    const st = await (0, import_promises.lstat)(full);
    if (!st.isFile() || st.isSymbolicLink()) continue;
    const rp = path.resolve(full);
    if (!rp.startsWith(baseDir + path.sep)) continue;
    sqls.push(name);
  }
  sqls.sort((a, b) => a.localeCompare(b, void 0, { numeric: true, sensitivity: "base" }));
  return sqls;
}
async function main() {
  const { dir, only, except, singleTx, dryRun } = parseArgs();
  const baseDir = path.resolve(dir);
  try {
    const st = await (0, import_promises.lstat)(baseDir);
    if (!st.isDirectory()) throw new Error(`${baseDir} is not a directory`);
  } catch (e) {
    console.error(`Directory not accessible: ${baseDir}
${e?.message || e}`);
    process.exit(1);
  }
  let files = await listSqlFiles(baseDir);
  if (only.length) files = files.filter((f) => matchAny(f, only));
  if (except.length) files = files.filter((f) => !matchAny(f, except));
  console.log(`Directory: ${baseDir}`);
  console.log(`Selected ${files.length} file(s):`);
  files.forEach((f) => console.log(`  - ${f}`));
  if (!files.length) {
    console.log("Nothing to do.");
    return;
  }
  if (dryRun) {
    console.log("Dry run: not executing SQL.");
    return;
  }
  const prisma = new import_client.PrismaClient();
  const runFile = async (exec, file) => {
    const full = path.join(baseDir, file);
    const sql = await fs.readFile(full, "utf8");
    if (!sql.trim()) {
      console.log(`(skip empty) ${file}`);
      return;
    }
    if (containsPsqlMeta(sql)) {
      throw new Error(
        `psql meta-commands (\\*) detected in ${file}. Prisma cannot execute them. Use a psql-based runner or remove meta-commands.`
      );
    }
    const statements = splitPostgresStatements(sql);
    console.log(`Executing: ${file} (${statements.length} statement${statements.length === 1 ? "" : "s"})`);
    for (let idx = 0; idx < statements.length; idx++) {
      const stmt = statements[idx].trim();
      if (!stmt) continue;
      try {
        await exec.$executeRawUnsafe(stmt);
      } catch (e) {
        console.error(`  \u2716 Failed at statement #${idx + 1}:
${stmt}
  \u2192 ${e.message}`);
        throw e;
      }
    }
    console.log(`\u2714 ${file}`);
  };
  try {
    if (singleTx) {
      console.log("Running all files in a single transaction...");
      await prisma.$transaction(async (tx) => {
        for (const f of files) {
          await runFile(tx, f);
        }
      });
      console.log("All done.");
    } else {
      for (const f of files) {
        try {
          await prisma.$transaction(async (tx) => {
            await runFile(tx, f);
          });
        } catch (e) {
          console.error(`\u2716 ${f} failed: ${e.message}`);
          process.exit(1);
        }
      }
      console.log("All done.");
    }
  } finally {
    await prisma.$disconnect();
  }
}
main().catch((err) => {
  console.error("Failed:", err);
  process.exit(1);
});
