import type { TableInfo } from "./getTablesInSchema";
import { pubName, subName } from "./names";
import { ident, join, sql } from "./quote";
import { runSql } from "./runSql";

/**
 * Copies DDL and creates publication/subscription which starts copying the
 * data. The data continues copying in background.
 */
export async function startCopyingTables({
  fromDsn,
  tables,
  toDsn,
  schema,
}: {
  fromDsn: string;
  tables: TableInfo[];
  toDsn: string;
  schema: string;
}): Promise<void> {
  if (tables.length === 0) {
    return;
  }

  await runSql(
    fromDsn,
    // "FOR TABLES IN SCHEMA ..." is supported since PG15+ only, so enumerating
    // all the tables explicitly.
    sql`CREATE PUBLICATION ${ident(pubName(schema))} FOR TABLE ${join(
      tables.map(({ schema, name }) => sql`${ident(schema)}.${ident(name)}`),
      ", ",
    )}`,
    "Creating source publication",
  );
  // We create the replication slot separately only to be able to test the tool
  // on dev: without a replication slot, when using the same database as a
  // source and destination, CREATE SUBSCRIPTION operation hangs (weird
  // documented behavior).
  await runSql(
    fromDsn,
    sql`SELECT pg_create_logical_replication_slot(${subName(schema)}, 'pgoutput')`,
  );
  await runSql(
    toDsn,
    sql`
      CREATE SUBSCRIPTION ${ident(subName(schema))}
      CONNECTION ${fromDsn}
      PUBLICATION ${ident(pubName(schema))}
      WITH (create_slot=false, streaming=on)
    `,
    "Creating destination subscription",
  );
}
