import { strict as assert } from "node:assert";
import { describe, it } from "node:test";
import { buildGeminiUserParts } from "../geminiMultimodalParts.ts";

describe("buildGeminiUserParts", () => {
  it("returns text-only part when no images", async () => {
    const parts = await buildGeminiUserParts("hello");
    assert.deepEqual(parts, [{ text: "hello" }]);
  });

  it("embeds base64 inlineData before text", async () => {
    const parts = await buildGeminiUserParts("describe", [
      { data: "aGVsbG8=", mimeType: "image/png" },
    ]);
    assert.equal(parts.length, 2);
    assert.deepEqual(parts[0], {
      inlineData: { mimeType: "image/png", data: "aGVsbG8=" },
    });
    assert.deepEqual(parts[1], { text: "describe" });
  });

  it("strips data URL prefix from base64 payload", async () => {
    const parts = await buildGeminiUserParts("", [
      {
        data: "data:image/jpeg;base64,YWJj",
        mimeType: "image/jpeg",
      },
    ]);
    assert.deepEqual(parts[0], {
      inlineData: { mimeType: "image/jpeg", data: "YWJj" },
    });
  });

  it("fetches http url into inlineData", async () => {
    const pngBytes = Buffer.from([0x89, 0x50, 0x4e, 0x47]);
    const fetchImpl = async () =>
      ({
        ok: true,
        headers: { get: () => "image/png" },
        arrayBuffer: async () => pngBytes.buffer.slice(pngBytes.byteOffset, pngBytes.byteOffset + pngBytes.byteLength),
      }) as unknown as Response;

    const parts = await buildGeminiUserParts("see image", [{ url: "https://example.test/x.png" }], {
      fetchImpl: fetchImpl as typeof fetch,
    });
    assert.equal(parts.length, 2);
    assert.equal((parts[0] as { inlineData: { mimeType: string } }).inlineData.mimeType, "image/png");
    assert.equal(
      (parts[0] as { inlineData: { data: string } }).inlineData.data,
      pngBytes.toString("base64"),
    );
  });

  it("skips failed url fetch but keeps text", async () => {
    const fetchImpl = async () => {
      throw new Error("network");
    };
    const parts = await buildGeminiUserParts("only text", [{ url: "https://bad.test/x.png" }], {
      fetchImpl: fetchImpl as typeof fetch,
    });
    assert.deepEqual(parts, [{ text: "only text" }]);
  });
});
