import { describe, expect, it } from "vitest";
import {
  INTERNAL_SESSION_HEADER,
  LoginRateLimiter,
  clearSessionCookie,
  internalSessionHeaders,
  loginPage,
  mutationIsCrossSite,
  sessionFromCookie,
  setSessionCookie,
} from "../../../apps/web/src/session-gateway.js";

describe("ADR-0009 public session gateway", () => {
  it("uses only the __Host HttpOnly Secure SameSite=Lax cookie contract", () => {
    const cookie = setSessionCookie("opaque-token");
    expect(cookie).toBe("__Host-awp_session=opaque-token; Path=/; HttpOnly; Secure; SameSite=Lax");
    expect(cookie).not.toContain("Domain=");
    expect(sessionFromCookie(`other=x; ${cookie.split(";")[0]}; theme=dark`)).toBe("opaque-token");
    expect(clearSessionCookie()).toContain("Max-Age=0");
    expect(clearSessionCookie()).toContain("Secure");
  });

  it("constructs internal identity headers only from the opaque session reference", () => {
    expect(internalSessionHeaders("opaque-token", "application/json")).toEqual({
      [INTERNAL_SESSION_HEADER]: "opaque-token",
      "content-type": "application/json",
    });
    expect(JSON.stringify(internalSessionHeaders("opaque-token"))).not.toMatch(
      /principal|capabilit/iu,
    );
  });

  it("rejects cross-site mutations while leaving safe reads unaffected", () => {
    expect(
      mutationIsCrossSite({ method: "POST", secFetchSite: "cross-site", host: "awp.test" }),
    ).toBe(true);
    expect(
      mutationIsCrossSite({
        method: "POST",
        origin: "https://evil.test",
        host: "awp.test",
      }),
    ).toBe(true);
    expect(
      mutationIsCrossSite({
        method: "POST",
        origin: "https://awp.test",
        host: "awp.test",
        secFetchSite: "same-origin",
      }),
    ).toBe(false);
    expect(
      mutationIsCrossSite({
        method: "GET",
        origin: "https://evil.test",
        host: "awp.test",
        secFetchSite: "cross-site",
      }),
    ).toBe(false);
  });

  it("rate limits repeated login attempts per caller", () => {
    let now = 1_000;
    const limiter = new LoginRateLimiter(2, 60_000, () => now);
    expect(limiter.allow("client-a")).toBe(true);
    expect(limiter.allow("client-a")).toBe(true);
    expect(limiter.allow("client-a")).toBe(false);
    expect(limiter.allow("client-b")).toBe(true);
    now += 60_000;
    expect(limiter.allow("client-a")).toBe(true);
    limiter.reset("client-a");
    expect(limiter.allow("client-a")).toBe(true);
  });

  it("escapes login errors", () => {
    const html = loginPage('<script>alert("x")</script>');
    expect(html).not.toContain("<script>alert");
    expect(html).toContain("&lt;script&gt;");
  });
});
