import type { PrismaClient } from "@prisma/client";

export interface SiloOrganization {
  readonly id: string;
  readonly slug: string;
  readonly name: string;
}

/**
 * Read the deployment-pinned Organization identity. A Silo process must never
 * infer its tenant from request data or from whichever row happens to exist.
 */
export function readSiloOrganizationId(
  env: Readonly<Record<string, string | undefined>> = process.env,
): string {
  const organizationId = env["HUB_SILO_ORGANIZATION_ID"]?.trim();
  if (organizationId === undefined || organizationId === "") {
    throw new Error("HUB_SILO_ORGANIZATION_ID is required");
  }
  return organizationId;
}

/**
 * Prove the database is a single-tenant Silo before accepting traffic.
 * Archived rows count too: pointing a Silo process at a pooled or reused
 * database is a deployment error, not a condition to paper over.
 */
export async function requireSiloOrganization(
  prisma: PrismaClient,
  organizationId: string,
): Promise<SiloOrganization> {
  const [count, organization] = await Promise.all([
    prisma.organization.count(),
    prisma.organization.findUnique({
      where: { id: organizationId },
      select: { id: true, slug: true, name: true, status: true },
    }),
  ]);
  if (count !== 1) {
    throw new Error(`Silo database must contain exactly one Organization; found ${count}`);
  }
  if (organization === null) {
    throw new Error(
      `Silo Organization mismatch: configured ${organizationId} is not the sole database Organization`,
    );
  }
  if (organization.status !== "ACTIVE") {
    throw new Error(`Silo Organization ${organizationId} is ${organization.status}`);
  }
  return { id: organization.id, slug: organization.slug, name: organization.name };
}
