import { execSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { ValidationPipe } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { SwaggerModule } from "@nestjs/swagger";
import { AppModule } from "../src/app.module";
import { buildSwaggerConfig } from "../src/swagger.config";

const SNAPSHOT = resolve(__dirname, "../docs/openapi/openapi.json");

async function main() {
  process.env.NODE_ENV = process.env.NODE_ENV ?? "test";
  const app = await NestFactory.create(AppModule, { logger: false });
  app.setGlobalPrefix("v1", { exclude: ["health", "/", "docs", "docs-json"] });
  app.useGlobalPipes(
    new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }),
  );

  const config = buildSwaggerConfig({ serverUrl: "https://api.novasis.io" });
  const document = SwaggerModule.createDocument(app, config);
  await app.close();

  const current = JSON.stringify(document, null, 2) + "\n";
  const committed = readFileSync(SNAPSHOT, "utf8");

  if (current === committed) {
    // eslint-disable-next-line no-console
    console.log("OpenAPI snapshot up to date.");
    return;
  }

  // eslint-disable-next-line no-console
  console.error("OpenAPI snapshot is stale. Run `pnpm openapi:snapshot` and commit the result.");
  try {
    execSync(`diff -u ${SNAPSHOT} -`, { input: current, stdio: ["pipe", "inherit", "inherit"] });
  } catch {
    // diff exits 1 when there are differences — already piped to stderr above.
  }
  process.exit(1);
}

void main().catch((err) => {
  // eslint-disable-next-line no-console
  console.error(err);
  process.exit(1);
});
