import { runSchemaMigrations } from "../../../db/migration.js";
import { cdcSchema } from "../../../types/shards.js";
import { setupCDCTables, createBackfillTables, createReplicationStateTable } from "./tables.js";
async function migrateFromLegacySchemas(lc, db, newSchema, ...legacy) {
  const rows = await db`
    SELECT nspname FROM pg_namespace 
      WHERE nspname IN ${db([newSchema, ...legacy])}`.values();
  const names = rows.flat();
  if (names.includes(newSchema)) {
    return;
  }
  for (const schema of legacy) {
    if (names.includes(schema)) {
      lc.info?.(`Migrating ${schema} to ${newSchema}`);
      await db`ALTER SCHEMA ${db(schema)} RENAME TO ${db(newSchema)}`;
      break;
    }
  }
}
async function initChangeStreamerSchema(log, db, shard) {
  const schema = cdcSchema(shard);
  const { appID } = shard;
  await migrateFromLegacySchemas(
    log,
    db,
    schema,
    appID === "zero" ? `cdc_0` : `cdc_${appID}`,
    "cdc"
  );
  const setupMigration = {
    migrateSchema: (lc, tx) => setupCDCTables(lc, tx, shard),
    minSafeVersion: 1
  };
  async function migrateV1toV2(_, db2) {
    await db2`
    ALTER TABLE ${db2(schema)}."replicationConfig" ADD "resetRequired" BOOL`;
  }
  const migrateV2ToV3 = {
    migrateSchema: async (_, db2) => {
      await db2.unsafe(createReplicationStateTable(shard));
    },
    migrateData: async (_, db2) => {
      const lastWatermark = await getLastWatermarkV2(db2, shard);
      const replicationState = { lastWatermark };
      await db2`
      TRUNCATE TABLE ${db2(schema)}."replicationState"`;
      await db2`
      INSERT INTO ${db2(schema)}."replicationState" ${db2(replicationState)}`;
    }
  };
  const migrateV3ToV4 = {
    migrateSchema: async (_, db2) => {
      await db2`
      ALTER TABLE ${db2(schema)}."changeLog" ALTER "change" TYPE JSON;
      `;
    }
  };
  const migrateV4ToV5 = {
    migrateSchema: async (_, db2) => {
      await db2`
      ALTER TABLE ${db2(schema)}."replicationState" ADD "ownerAddress" TEXT;
      `;
    }
  };
  const migrateV5ToV6 = {
    migrateSchema: async (_, db2) => {
      await db2.unsafe(createBackfillTables(shard));
    }
  };
  const schemaVersionMigrationMap = {
    2: { migrateSchema: migrateV1toV2 },
    3: migrateV2ToV3,
    4: migrateV3ToV4,
    5: migrateV4ToV5,
    6: migrateV5ToV6
  };
  await runSchemaMigrations(
    log,
    "change-streamer",
    schema,
    db,
    setupMigration,
    schemaVersionMigrationMap
  );
}
async function getLastWatermarkV2(db, shard) {
  const schema = cdcSchema(shard);
  const [{ max }] = await db`
    SELECT MAX(watermark) as max FROM ${db(schema)}."changeLog"`;
  if (max !== null) {
    return max;
  }
  const [{ replicaVersion }] = await db`
    SELECT "replicaVersion" FROM ${db(schema)}."replicationConfig"
    `;
  return replicaVersion;
}
export {
  getLastWatermarkV2,
  initChangeStreamerSchema
};
//# sourceMappingURL=init.js.map
