import { databaseLogger } from "../logger.js";
import { DatabaseSaveTrigger } from "../database-save-trigger.js";
import { getCurrentRepositorySqlite } from "../../database/repositories/factory.js";
import {
  needsExplicitPersist,
  resolveDatabaseDialect,
} from "../../database/db/dialect.js";

interface SqliteLike {
  prepare(sql: string): {
    all(...params: unknown[]): unknown[];
    get(...params: unknown[]): unknown;
    run(...params: unknown[]): unknown;
  };
  exec(sql: string): unknown;
}

function tableHasColumn(
  sqlite: SqliteLike,
  table: string,
  column: string,
): boolean {
  const rows = sqlite.prepare(`PRAGMA table_info(${table})`).all() as Array<{
    name: string;
  }>;
  return rows.some((row) => row.name === column);
}

function dropColumnIfExists(
  sqlite: SqliteLike,
  table: string,
  column: string,
): boolean {
  if (!tableHasColumn(sqlite, table, column)) return false;
  sqlite.exec(`ALTER TABLE ${table} DROP COLUMN ${column}`);
  return true;
}

// One-time cleanup of the pre-2.5 sharing machinery: the
// CREDENTIAL_SHARING_KEY shadow columns are dropped. Pending share copies are
// no longer re-created here; the shared_host_secrets migration rebuilds every
// active share from the live host_access grants instead.
export async function runLegacySharedCredentialCleanup(): Promise<{
  columnsDropped: number;
}> {
  const result = { columnsDropped: 0 };

  // Nothing to clean up on an engine this application has never run on. A
  // Postgres or MySQL database is created by the drizzle migrations, which have
  // never emitted these legacy columns, so there is nothing to drop — and the
  // check itself needs a synchronous PRAGMA that only SQLite offers.
  if (!needsExplicitPersist(resolveDatabaseDialect())) return result;

  const sqlite = getCurrentRepositorySqlite() as unknown as SqliteLike;

  for (const [table, column] of [
    ["ssh_credentials", "system_password"],
    ["ssh_credentials", "system_key"],
    ["ssh_credentials", "system_key_password"],
  ] as const) {
    if (dropColumnIfExists(sqlite, table, column)) {
      result.columnsDropped++;
    }
  }

  if (result.columnsDropped) {
    await DatabaseSaveTrigger.forceSave("legacy_share_cleanup");
    databaseLogger.info("Legacy shared-credential cleanup finished", {
      operation: "legacy_share_cleanup",
      ...result,
    });
  }

  return result;
}
