import compact from "lodash/compact";
import { join, sql } from "./quote";
import { runSql } from "./runSql";

/**
 * Advances all sequences on the destination (including sequences in other
 * schemas), so their values won't conflict with the ones on the source.
 */
export async function advanceSequences({
  fromDsn,
  toDsn,
}: {
  fromDsn: string;
  toDsn: string;
}): Promise<void> {
  const fromSequences = await runSql(
    fromDsn,
    sql`
      SELECT
        quote_ident(sequence_schema) || '.' || quote_ident(sequence_name),
        nextval(quote_ident(sequence_schema) || '.' || quote_ident(sequence_name))::text
      FROM information_schema.sequences
      ORDER BY 1
    `,
  );
  const toSequences = await runSql.column(
    toDsn,
    sql`
      SELECT quote_ident(sequence_schema) || '.' || quote_ident(sequence_name)
      FROM information_schema.sequences
    `,
  );
  const toSql = compact(
    fromSequences.map(([sequence, value]) =>
      toSequences.includes(sequence)
        ? sql`SELECT setval(${sequence}, GREATEST(nextval(${sequence}), ${value}) + 1000);`
        : null,
    ),
  );
  if (toSql.length > 0) {
    await runSql(toDsn, join(toSql, "\n"), "Advancing destination sequences");
  }
}
