#!/usr/bin/env node
/**
 * ensurePromptTemplates — runs at every container boot from
 * docker_entrypoint.sh. Reconciles the curated built-in AI prompt
 * templates from /app/prisma/aiTemplates.seed.json into the
 * AIPromptTemplate table. Built-ins have userId=NULL.
 *
 *   - INSERT new built-in templates that don't exist by name yet.
 *   - UPDATE existing built-ins (userId IS NULL) by name to match
 *     the curated systemPrompt + userPromptTemplate. Maintainer-side
 *     fixes propagate to existing installs.
 *   - User-created templates (userId IS NOT NULL) are never touched
 *     here, even if a user happens to have created a template with
 *     the same name as a built-in.
 *
 * Idempotent. Cheap (5 templates × 1 transaction).
 */

const fs = require('fs');
const crypto = require('crypto');
const { execFileSync } = require('child_process');

function arg(name) {
  const i = process.argv.indexOf(name);
  return i >= 0 ? process.argv[i + 1] : null;
}

const dbPath = arg('--db');
const jsonPath = arg('--json');
if (!dbPath || !jsonPath) {
  console.error(
    'usage: ensurePromptTemplates.cjs --db <path> --json <path>',
  );
  process.exit(64);
}
if (!fs.existsSync(dbPath)) {
  console.error(`[ensure-templates] db not found: ${dbPath}`);
  process.exit(0);
}
if (!fs.existsSync(jsonPath)) {
  console.error(`[ensure-templates] templates json not found: ${jsonPath}`);
  process.exit(0);
}

// Defensive: only run if the table exists (compat ALTER may not have
// run yet on a brand-new install where seed.ts ran instead).
const hasTable = execFileSync(
  'sqlite3',
  [
    dbPath,
    "SELECT name FROM sqlite_master WHERE type='table' AND name='AIPromptTemplate';",
  ],
  { encoding: 'utf8' },
).trim();
if (!hasTable) {
  console.error('[ensure-templates] AIPromptTemplate table not found; skipping');
  process.exit(0);
}

const templates = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
if (!Array.isArray(templates) || templates.length === 0) {
  console.error('[ensure-templates] templates array is empty; nothing to do');
  process.exit(0);
}

const q = (s) => `'${String(s).replace(/'/g, "''")}'`;
const newId = () => 'c' + crypto.randomBytes(12).toString('hex');

// SQLite doesn't have a partial unique index easy to install via
// schema, so we manually upsert: SELECT-by-name-where-builtin first,
// then INSERT or UPDATE.
const stmts = ['BEGIN;'];
for (const t of templates) {
  // Find existing built-in with this name. We use COALESCE-by-rowid
  // to make this single-statement-friendly with INSERT OR REPLACE.
  // Easier: do explicit lookup + branch in JS.
  const existingRows = execFileSync(
    'sqlite3',
    [
      dbPath,
      `SELECT id FROM AIPromptTemplate WHERE userId IS NULL AND name = ${q(t.name)};`,
    ],
    { encoding: 'utf8' },
  )
    .split('\n')
    .filter(Boolean);
  const existingId = existingRows[0];

  if (existingId) {
    stmts.push(
      `UPDATE AIPromptTemplate SET ` +
        `description = ${t.description ? q(t.description) : 'NULL'}, ` +
        `systemPrompt = ${q(t.systemPrompt)}, ` +
        `userPromptTemplate = ${q(t.userPromptTemplate)}, ` +
        `isBuiltIn = 1, ` +
        `updatedAt = CURRENT_TIMESTAMP ` +
        `WHERE id = ${q(existingId)};`,
    );
  } else {
    stmts.push(
      `INSERT INTO AIPromptTemplate ` +
        `(id, userId, name, description, systemPrompt, userPromptTemplate, isBuiltIn, createdAt, updatedAt) ` +
        `VALUES (${q(newId())}, NULL, ${q(t.name)}, ` +
        `${t.description ? q(t.description) : 'NULL'}, ` +
        `${q(t.systemPrompt)}, ${q(t.userPromptTemplate)}, ` +
        `1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);`,
    );
  }
}
stmts.push('COMMIT;');

execFileSync('sqlite3', [dbPath], { input: stmts.join('\n') });
console.error(
  `[ensure-templates] reconciled ${templates.length} built-in template(s)`,
);
