/* eslint-disable no-non-null-assertion -- test assertions on defined objects */
import { Effect } from "effect";
import { describe, expect, it } from "vitest";

import { OrbConfigurationError } from "./domain";
import {
  opencodeSetupCommands,
  prepareOpenCodeConfig,
} from "./opencode-config";

const validGateway = {
  apiKey: "test-key-123",
  baseUrl: "https://gateway.example.com/v1",
  model: "test-model",
  provider: "test-provider",
};

const validContext = {
  artifacts: [],
  contextFiles: [],
  issueBody: "Fix the bug",
  issueTitle: "Bug fix",
  repositoryUrl: undefined,
};

describe("prepareOpenCodeConfig", () => {
  it("produces valid config JSON with provider and model", () => {
    const result = Effect.runSync(
      prepareOpenCodeConfig({
        context: validContext,
        gateway: validGateway,
      })
    );
    const parsed = JSON.parse(result.configJson);
    expect(parsed.model).toBe("test-provider/test-model");
    expect(parsed.provider["test-provider"].baseUrl).toBe(
      "https://gateway.example.com/v1"
    );
    expect(parsed.provider["test-provider"].apiKey).toBe("test-key-123");
  });

  it("sets config path under opencode config directory", () => {
    const result = Effect.runSync(
      prepareOpenCodeConfig({
        context: validContext,
        gateway: validGateway,
      })
    );
    expect(result.configPath).toContain("opencode");
    expect(result.configPath).toContain("config.json");
    expect(result.instructionsPath).toBe("/workspace/control/issue.md");
  });

  it("rejects empty base URL", () => {
    const error = Effect.runSync(
      Effect.flip(
        prepareOpenCodeConfig({
          context: validContext,
          gateway: { ...validGateway, baseUrl: "  " },
        })
      )
    );
    expect(error).toBeInstanceOf(OrbConfigurationError);
    expect(error.reason).toBe("InvalidModelConfig");
  });
});

describe("opencodeSetupCommands", () => {
  it("produces mkdir, write, and chmod commands", () => {
    const config = Effect.runSync(
      prepareOpenCodeConfig({
        context: validContext,
        gateway: validGateway,
      })
    );
    const commands = opencodeSetupCommands(config);
    expect(commands.length).toBe(3);
    expect(commands[0]).toContain("mkdir");
    expect(commands[1]).toContain("cat >");
    expect(commands[2]).toContain("chmod 600");
  });
});
