/**
 * embedding-provider.test.ts - Tests for the EmbeddingProvider abstraction
 * (interface-level: model-id guard, ModelMismatchError).
 */

import { describe, test, expect } from "vitest";
import {
  ModelMismatchError,
  assertModelCompatible,
} from "../src/embedding/provider.js";

describe("assertModelCompatible", () => {
  test("empty existingModels → no throw (fresh DB)", () => {
    expect(() => assertModelCompatible("anything", [])).not.toThrow();
  });

  test("matching model id → no throw", () => {
    expect(() =>
      assertModelCompatible("embeddinggemma", ["embeddinggemma"]),
    ).not.toThrow();
  });

  test("matching one of several → no throw", () => {
    expect(() =>
      assertModelCompatible("embeddinggemma", ["embeddinggemma", "qwen3-embed"]),
    ).not.toThrow();
  });

  test("mismatch throws ModelMismatchError", () => {
    expect(() =>
      assertModelCompatible("openai-text-embedding", ["embeddinggemma"]),
    ).toThrow(ModelMismatchError);
  });

  test("error message lists existing models + provider model", () => {
    try {
      assertModelCompatible("provider-x", ["model-a", "model-b"]);
      throw new Error("should have thrown");
    } catch (err) {
      expect(err).toBeInstanceOf(ModelMismatchError);
      const e = err as ModelMismatchError;
      expect(e.providerModel).toBe("provider-x");
      expect(e.existingModels).toEqual(["model-a", "model-b"]);
      expect(e.message).toContain("provider-x");
      expect(e.message).toContain("model-a");
      expect(e.message).toContain("qmd embed -f");
      expect(e.message).toContain("QMD_EMBED_MODEL_ID");
    }
  });
});

describe("ModelMismatchError", () => {
  test("name set correctly", () => {
    const err = new ModelMismatchError("a", ["b"]);
    expect(err.name).toBe("ModelMismatchError");
  });

  test("instanceof Error", () => {
    const err = new ModelMismatchError("a", ["b"]);
    expect(err).toBeInstanceOf(Error);
    expect(err).toBeInstanceOf(ModelMismatchError);
  });
});
