import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../../config/config.js";
import {
  buildEmbeddedCompactionRuntimeContext,
  resolveEmbeddedCompactionTarget,
} from "./compaction-runtime-context.js";

describe("buildEmbeddedCompactionRuntimeContext", () => {
  it("preserves sender and current message routing for compaction", () => {
    expect(
      buildEmbeddedCompactionRuntimeContext({
        sessionKey: "agent:main:thread:1",
        messageChannel: "slack",
        messageProvider: "slack",
        agentAccountId: "acct-1",
        currentChannelId: "C123",
        currentThreadTs: "thread-9",
        currentMessageId: "msg-42",
        authProfileId: "openai:p1",
        workspaceDir: "/tmp/workspace",
        agentDir: "/tmp/agent",
        config: {} as OpenClawConfig,
        senderIsOwner: true,
        senderId: "user-123",
        provider: "openai-codex",
        modelId: "gpt-5.4",
        thinkLevel: "off",
        reasoningLevel: "on",
        extraSystemPrompt: "extra",
        ownerNumbers: ["+15555550123"],
      }),
    ).toMatchObject({
      sessionKey: "agent:main:thread:1",
      messageChannel: "slack",
      messageProvider: "slack",
      agentAccountId: "acct-1",
      currentChannelId: "C123",
      currentThreadTs: "thread-9",
      currentMessageId: "msg-42",
      authProfileId: "openai:p1",
      workspaceDir: "/tmp/workspace",
      agentDir: "/tmp/agent",
      senderId: "user-123",
      provider: "openai-codex",
      model: "gpt-5.4",
    });
  });

  it("normalizes nullable compaction routing fields to undefined", () => {
    expect(
      buildEmbeddedCompactionRuntimeContext({
        sessionKey: null,
        messageChannel: null,
        messageProvider: null,
        agentAccountId: null,
        currentChannelId: null,
        currentThreadTs: null,
        currentMessageId: null,
        authProfileId: null,
        workspaceDir: "/tmp/workspace",
        agentDir: "/tmp/agent",
        senderId: null,
        provider: null,
        modelId: null,
      }),
    ).toMatchObject({
      sessionKey: undefined,
      messageChannel: undefined,
      messageProvider: undefined,
      agentAccountId: undefined,
      currentChannelId: undefined,
      currentThreadTs: undefined,
      currentMessageId: undefined,
      authProfileId: undefined,
      senderId: undefined,
      provider: undefined,
      model: undefined,
    });
  });

  it("applies compaction.model override with provider/model format", () => {
    const result = buildEmbeddedCompactionRuntimeContext({
      workspaceDir: "/tmp/workspace",
      agentDir: "/tmp/agent",
      config: {
        agents: { defaults: { compaction: { model: "anthropic/claude-opus-4-6" } } },
      } as OpenClawConfig,
      provider: "ollama",
      modelId: "minimax-m2.7:cloud",
      authProfileId: "ollama:default",
    });
    expect(result.provider).toBe("anthropic");
    expect(result.model).toBe("claude-opus-4-6");
    // Auth profile dropped because provider changed
    expect(result.authProfileId).toBeUndefined();
  });

  it("applies compaction.model override with model-only format", () => {
    const result = buildEmbeddedCompactionRuntimeContext({
      workspaceDir: "/tmp/workspace",
      agentDir: "/tmp/agent",
      config: {
        agents: { defaults: { compaction: { model: "gpt-4o" } } },
      } as OpenClawConfig,
      provider: "openai",
      modelId: "gpt-3.5-turbo",
      authProfileId: "openai:p1",
    });
    expect(result.provider).toBe("openai");
    expect(result.model).toBe("gpt-4o");
    // Auth profile preserved because provider didn't change
    expect(result.authProfileId).toBe("openai:p1");
  });

  it("uses session model when no compaction.model override configured", () => {
    const result = buildEmbeddedCompactionRuntimeContext({
      workspaceDir: "/tmp/workspace",
      agentDir: "/tmp/agent",
      config: {} as OpenClawConfig,
      provider: "ollama",
      modelId: "minimax-m2.7:cloud",
      authProfileId: "ollama:default",
    });
    expect(result.provider).toBe("ollama");
    expect(result.model).toBe("minimax-m2.7:cloud");
    expect(result.authProfileId).toBe("ollama:default");
  });

  it("applies runtime defaults when resolving the effective compaction target", () => {
    expect(
      resolveEmbeddedCompactionTarget({
        config: {
          agents: { defaults: { compaction: { model: "anthropic/" } } },
        } as OpenClawConfig,
        provider: "openai-codex",
        modelId: "gpt-5.4",
        authProfileId: "openai:p1",
        defaultProvider: "openai-codex",
        defaultModel: "gpt-5.4",
      }),
    ).toEqual({
      provider: "anthropic",
      model: "gpt-5.4",
      authProfileId: undefined,
    });
  });
});
