import { spawn } from 'child_process';

const MAX_ATTEMPTS = 4;
const BACKOFFS_MS = [3000, 8000, 20000, 45000];

function runPrismaDbPush() {
  return new Promise((resolve, reject) => {
    let stderr = '';
    const proc = spawn('npx', ['prisma', 'db', 'push', '--accept-data-loss'], { stdio: ['inherit', 'inherit', 'pipe'] });
    proc.stderr.on('data', (chunk) => {
      const text = chunk.toString();
      stderr += text;
      process.stderr.write(text);
    });
    proc.on('close', (code) => {
      if (code === 0) resolve();
      else reject(Object.assign(new Error(`prisma db push exited ${code}`), { stderr }));
    });
  });
}

for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
  try {
    console.log(`[prisma-db-push] Attempt ${attempt}/${MAX_ATTEMPTS}...`);
    await runPrismaDbPush();
    console.log('[prisma-db-push] Success.');
    process.exit(0);
  } catch (err) {
    const isP1001 = String(err.stderr || err.message).includes('P1001') || String(err.stderr || err.message).includes("Can't reach database server");
    if (!isP1001 || attempt === MAX_ATTEMPTS) {
      console.error(`[prisma-db-push] Final failure on attempt ${attempt}.`);
      process.exit(1);
    }
    const waitMs = BACKOFFS_MS[attempt - 1];
    console.log(`[prisma-db-push] P1001 on attempt ${attempt}. Waiting ${waitMs / 1000}s for Neon to wake...`);
    await new Promise((r) => setTimeout(r, waitMs));
  }
}
