import { describe, expect, it } from "vitest";
import { assertSecureRuntimeEnv, getRuntimeEnvViolations } from "./runtime-env";

describe("runtime env validation", () => {
  it("allows non-production environments without auth runtime settings", () => {
    expect(getRuntimeEnvViolations({ NODE_ENV: "development" })).toEqual([]);
  });

  it("accepts a valid production auth secret and https url", () => {
    expect(
      getRuntimeEnvViolations({
        NODE_ENV: "production",
        NEXTAUTH_SECRET: "super-long-random-secret-with-enough-entropy-abc123",
        NEXTAUTH_URL: "https://capakraken.example.com",
      }),
    ).toEqual([]);
  });

  it("rejects a missing production auth secret", () => {
    expect(
      getRuntimeEnvViolations({
        NODE_ENV: "production",
        NEXTAUTH_URL: "https://capakraken.example.com",
      }),
    ).toContain("AUTH_SECRET or NEXTAUTH_SECRET must be set in production.");
  });

  it("rejects the development placeholder auth secret in production", () => {
    expect(
      getRuntimeEnvViolations({
        NODE_ENV: "production",
        NEXTAUTH_SECRET: "dev-secret-change-in-production",
        NEXTAUTH_URL: "https://capakraken.example.com",
      }),
    ).toContain(
      "AUTH_SECRET or NEXTAUTH_SECRET must not use a known development placeholder in production.",
    );
  });

  it("rejects an auth secret shorter than the minimum length in production", () => {
    expect(
      getRuntimeEnvViolations({
        NODE_ENV: "production",
        NEXTAUTH_SECRET: "short-but-random-xyz", // 20 chars
        NEXTAUTH_URL: "https://capakraken.example.com",
      }),
    ).toContain("AUTH_SECRET or NEXTAUTH_SECRET must be at least 32 characters in production.");
  });

  it("rejects a long-but-low-entropy auth secret in production", () => {
    expect(
      getRuntimeEnvViolations({
        NODE_ENV: "production",
        NEXTAUTH_SECRET: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // 38 a's
        NEXTAUTH_URL: "https://capakraken.example.com",
      }),
    ).toContain(
      "AUTH_SECRET or NEXTAUTH_SECRET entropy is too low; generate with `openssl rand -base64 32`.",
    );
  });

  it("rejects non-https auth urls in production", () => {
    expect(
      getRuntimeEnvViolations({
        NODE_ENV: "production",
        NEXTAUTH_SECRET: "super-long-random-secret-with-enough-entropy-abc123",
        NEXTAUTH_URL: "http://capakraken.example.com",
      }),
    ).toContain("AUTH_URL or NEXTAUTH_URL must use https in production.");
  });

  it("throws with a combined startup error when production env is invalid", () => {
    expect(() =>
      assertSecureRuntimeEnv({
        NODE_ENV: "production",
        NEXTAUTH_SECRET: "dev-secret-change-in-production",
        NEXTAUTH_URL: "not-a-url",
      }),
    ).toThrow(/Invalid production runtime configuration/);
  });
});
