import { PrismaClient } from '@prisma/client';

const TEST_DATABASE_URL = process.env['DATABASE_URL'] ??
  'postgresql://mcpctl:mcpctl_test@localhost:5433/mcpctl_test';

let prisma: PrismaClient | undefined;

export function getTestClient(): PrismaClient {
  if (!prisma) {
    prisma = new PrismaClient({
      datasources: { db: { url: TEST_DATABASE_URL } },
    });
  }
  return prisma;
}

/** Return a connected test client. Schema is pushed by globalSetup. */
export async function setupTestDb(): Promise<PrismaClient> {
  return getTestClient();
}

export async function cleanupTestDb(): Promise<void> {
  if (prisma) {
    await prisma.$disconnect();
    prisma = undefined;
  }
}

export async function clearAllTables(client: PrismaClient): Promise<void> {
  // Delete in order respecting foreign keys
  await client.auditEvent.deleteMany();
  await client.auditLog.deleteMany();
  await client.chatMessage.deleteMany();
  await client.chatThread.deleteMany();
  await client.personalityPrompt.deleteMany();
  // Break Agent.defaultPersonalityId before personalities can be removed.
  await client.agent.updateMany({ data: { defaultPersonalityId: null } });
  await client.personality.deleteMany();
  // Skills + Proposals cascade from Project/Agent, but globals (NULL FK)
  // need explicit cleanup so they don't leak between tests.
  await client.skill.deleteMany();
  await client.resourceProposal.deleteMany();
  // Revisions have no FK (soft FK); always orphans without explicit clear.
  await client.resourceRevision.deleteMany();
  await client.agent.deleteMany();
  await client.llm.deleteMany();
  await client.mcpInstance.deleteMany();
  await client.promptRequest.deleteMany();
  await client.prompt.deleteMany();
  await client.projectServer.deleteMany();
  await client.secret.deleteMany();
  await client.session.deleteMany();
  await client.project.deleteMany();
  await client.mcpServer.deleteMany();
  await client.mcpTemplate.deleteMany();
  await client.groupMember.deleteMany();
  await client.group.deleteMany();
  await client.rbacDefinition.deleteMany();
  await client.user.deleteMany();
}
