// engine/db/migrations/010-pr-links.js
//
// Phase 9.1: move `engine/pr-links.json` into SQL.
//
// pr-links.json is the *fallback* PR → work-item linkage store. The
// primary source is `pull_requests.prdItems[]` (managed via the
// pull-requests-store). Stray PR IDs that aren't covered by a project
// pull-requests record still need to be discoverable — that's what this
// table holds.
//
// Shape: { [prId]: <value> } where <value> is typically an array of item IDs
// but may also be a bare string from legacy writes. Readers normalize.

const path = require('path');
const fs = require('fs');

function _resolveMinionsDir() {
  const envHome = process.env.MINIONS_HOME || process.env.MINIONS_TEST_DIR;
  if (envHome) return envHome;
  try { return require('../../shared').MINIONS_DIR; } catch { return null; }
}

function _readJsonOr(filePath, fallback) {
  try {
    const raw = fs.readFileSync(filePath, 'utf8');
    return JSON.parse(raw);
  } catch { return fallback; }
}

module.exports = {
  version: 10,
  description: 'pr_links: schema + pr-links.json backfill (fallback static store)',
  up(db) {
    db.exec(`
      CREATE TABLE pr_links (
        pr_id      TEXT PRIMARY KEY,
        data       TEXT NOT NULL,
        updated_at INTEGER NOT NULL
      );
    `);

    const minionsDir = _resolveMinionsDir();
    if (!minionsDir) return;
    const now = Date.now();
    let inserted = 0;

    const raw = _readJsonOr(path.join(minionsDir, 'engine', 'pr-links.json'), null);
    if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
      const ins = db.prepare(`INSERT INTO pr_links (pr_id, data, updated_at) VALUES (?, ?, ?)`);
      for (const [prId, value] of Object.entries(raw)) {
        try {
          ins.run(String(prId), JSON.stringify(value), now);
          inserted += 1;
        } catch { /* duplicate / corrupt — skip */ }
      }
    }

    // eslint-disable-next-line no-console
    console.log(`[db-migrate] v10: backfilled ${inserted} pr-links rows; pr-links.json kept as dual-write mirror`);
  },
};
