import { describe, expect, it } from "vitest";

import { GeminiFlashAdapter } from "../../apps/worker/src/ai-adapter-gemini-flash.js";
import { GeminiProAdapter } from "../../apps/worker/src/ai-adapter-gemini-pro.js";
import { GptImageAdapter } from "../../apps/worker/src/ai-adapter-gpt-image.js";
import {
  gptImageRequestSizeForRatio,
  normalizeImageOutputToRatio,
  productDimensionsForRatio,
} from "../../apps/worker/src/image-output-normalizer.mjs";

const onePixelPng = Buffer.from(
  "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
  "base64",
);

describe("TDD-WP7-EXT-001 exact image output normalization", () => {
  it("uses only GPT Image 2 request sizes allowed by the upstream API", () => {
    expect(["3:4", "1:1", "4:3", "9:16"].map((ratio) => gptImageRequestSizeForRatio(ratio))).toEqual([
      "1056x1408",
      "1088x1088",
      "1408x1056",
      "1008x1792",
    ]);
    for (const ratio of ["3:4", "1:1", "4:3", "9:16"] as const) {
      const [width, height] = gptImageRequestSizeForRatio(ratio).split("x").map(Number);
      expect(width % 16).toBe(0);
      expect(height % 16).toBe(0);
    }
  });

  it("normalizes provider output to the frozen product dimensions", async () => {
    const output = await normalizeImageOutputToRatio({ bytes: onePixelPng, mimeType: "image/png", ratio: "1:1" });
    expect(output).toMatchObject({
      mimeType: "image/png",
      normalized: true,
      pixelHeight: 1080,
      pixelWidth: 1080,
      upstreamPixelHeight: 1,
      upstreamPixelWidth: 1,
    });
    expect(output.bytes.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a");
    expect(productDimensionsForRatio("9:16")).toEqual({ pixelHeight: 1920, pixelWidth: 1080 });
  });

  it("is used by all three production adapter boundaries", async () => {
    const encoded = onePixelPng.toString("base64");
    const adapters = [
      new GeminiFlashAdapter({ transport: {
        async start() { return { candidates: [{ inline_data: { data: encoded, mime_type: "image/png" }, pixelHeight: 1, pixelWidth: 1 }] }; },
        async poll() { return {}; },
      } }),
      new GeminiProAdapter({ transport: {
        async start() { return { operation: { done: true, response: { candidates: [{ inline_data: { data: encoded, mime_type: "image/png" }, pixelHeight: 1, pixelWidth: 1 }] } } }; },
        async poll() { return {}; },
      } }),
      new GptImageAdapter({ transport: {
        async start() { return { data: [{ b64_json: encoded, pixelHeight: 1, pixelWidth: 1 }] }; },
        async poll() { return {}; },
      } }),
    ];
    for (const adapter of adapters) {
      const result = await adapter.start({
        configSnapshot: {}, generationId: `normalization-${adapter.modelId}`, modelId: adapter.modelId,
        prompt: "sanitized fixture", ratio: "1:1", referenceAssetIds: [],
      });
      expect(result).toMatchObject({ status: "completed", outputs: [{ mimeType: "image/png", pixelHeight: 1080, pixelWidth: 1080 }] });
    }
  });
});
