/**
 * Cookie-hardening regression tests — security ticket #41.
 *
 * auth.config.ts uses module-level env reads, so we reset modules and stub
 * the relevant variables before each importing the module freshly.
 */

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

function originalEnvSnapshot() {
  return {
    AUTH_URL: process.env["AUTH_URL"],
    NEXTAUTH_URL: process.env["NEXTAUTH_URL"],
    VERCEL: process.env["VERCEL"],
    NODE_ENV: process.env["NODE_ENV"],
  };
}

describe("auth.config cookies", () => {
  let snapshot: ReturnType<typeof originalEnvSnapshot>;

  beforeEach(() => {
    snapshot = originalEnvSnapshot();
    delete process.env["AUTH_URL"];
    delete process.env["NEXTAUTH_URL"];
    delete process.env["VERCEL"];
    vi.resetModules();
  });

  afterEach(() => {
    for (const [k, v] of Object.entries(snapshot)) {
      if (v === undefined) delete process.env[k];
      else process.env[k] = v;
    }
    vi.resetModules();
  });

  it("sets secure=true and __Host- prefix when AUTH_URL is https", async () => {
    process.env["AUTH_URL"] = "https://app.example.com";
    const { authConfig } = await import("./auth.config.js");
    expect(authConfig.cookies?.sessionToken?.options?.secure).toBe(true);
    expect(authConfig.cookies?.sessionToken?.name).toBe("__Host-authjs.session-token");
    expect(authConfig.cookies?.callbackUrl?.name).toBe("__Host-authjs.callback-url");
    expect(authConfig.cookies?.csrfToken?.name).toBe("__Host-authjs.csrf-token");
  });

  it("sets secure=false on http deployment", async () => {
    process.env["AUTH_URL"] = "http://localhost:3000";
    const { authConfig } = await import("./auth.config.js");
    expect(authConfig.cookies?.sessionToken?.options?.secure).toBe(false);
    expect(authConfig.cookies?.sessionToken?.name).toBe("authjs.session-token");
  });

  it("ignores NODE_ENV — secure flag tied to AUTH_URL scheme only", async () => {
    // Staging: NODE_ENV=production but AUTH_URL is plain http → still insecure.
    // The point is that the flag should NOT depend on NODE_ENV any more.
    // (process.env.NODE_ENV is read-only in the Next.js tsconfig; force via index.)
    (process.env as Record<string, string>)["NODE_ENV"] = "production";
    process.env["AUTH_URL"] = "http://staging.internal";
    const { authConfig } = await import("./auth.config.js");
    expect(authConfig.cookies?.sessionToken?.options?.secure).toBe(false);
  });

  it("uses __Host- prefix on Vercel even without explicit AUTH_URL", async () => {
    process.env["VERCEL"] = "1";
    const { authConfig } = await import("./auth.config.js");
    expect(authConfig.cookies?.sessionToken?.options?.secure).toBe(true);
    expect(authConfig.cookies?.sessionToken?.name).toBe("__Host-authjs.session-token");
  });

  it("keeps sameSite=strict, httpOnly=true, path=/ in all configurations", async () => {
    process.env["AUTH_URL"] = "https://app.example.com";
    const { authConfig } = await import("./auth.config.js");
    const opts = authConfig.cookies?.sessionToken?.options;
    expect(opts?.sameSite).toBe("strict");
    expect(opts?.httpOnly).toBe(true);
    expect(opts?.path).toBe("/");
  });
});
