import { homedir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
  resolveConfigHomeFromEnv,
  resolveDimcodeConfigDir,
  resolveDimcodeStateDir,
  resolveDimcodeUserDir,
} from "../src/dimsdk/core/storage-paths.ts";
import {
  detectImageCapability,
  resolveStateDir as resolveServerStateDir,
} from "../src/dimsdk/commands/server-helpers.ts";
import { resolveStateDir as resolveBlobStateDir } from "../src/dimsdk/shared/session-blob.ts";

const originalDimcodeHome = process.env.DIMCODE_HOME;
const originalDimcodeStateDir = process.env.DIMCODE_STATE_DIR;

afterEach(() => {
  if (originalDimcodeHome == null) delete process.env.DIMCODE_HOME;
  else process.env.DIMCODE_HOME = originalDimcodeHome;

  if (originalDimcodeStateDir == null) delete process.env.DIMCODE_STATE_DIR;
  else process.env.DIMCODE_STATE_DIR = originalDimcodeStateDir;
});

describe("storage paths", () => {
  it("resolves config, user, and state paths from DIMCODE_HOME", () => {
    const env = {
      DIMCODE_HOME: "/tmp/dim-home",
    };

    expect(resolveConfigHomeFromEnv(env)).toBe("/tmp/dim-home");
    expect(resolveDimcodeConfigDir(env)).toBe("/tmp/dim-home");
    expect(resolveDimcodeUserDir(env)).toBe("/tmp/dim-home/dimcode");
    expect(resolveDimcodeStateDir(env)).toBe("/tmp/dim-home/state");
  });

  it("uses HOME when DIMCODE_HOME is unset", () => {
    const env = {
      HOME: "/tmp/home-user",
    };

    expect(resolveConfigHomeFromEnv(env)).toBe("/tmp/home-user/.dimcode");
    expect(resolveDimcodeConfigDir(env)).toBe("/tmp/home-user/.dimcode");
    expect(resolveDimcodeUserDir(env)).toBe("/tmp/home-user/.dimcode/dimcode");
    expect(resolveDimcodeStateDir(env)).toBe("/tmp/home-user/.dimcode/state");
  });

  it("falls back to cache-dir inference in server helpers when HOME is absent", () => {
    const cacheDir = "/tmp/project/.dimcode/dimcode";

    expect(resolveServerStateDir(cacheDir, {})).toBe("/tmp/project/.dimcode/state");
  });

  it("detects image support from builtin provider model metadata", () => {
    expect(
      detectImageCapability(
        {
          version: 1,
          updatedAt: 0,
          settings: {
            providerId: "anthropic",
            activeModelByProvider: {
              anthropic: "claude-opus-4-5-20251101",
            },
          },
        },
        {},
      ),
    ).toBe(true);
  });

  it("detects image support from persisted custom model metadata", () => {
    expect(
      detectImageCapability(
        {
          version: 1,
          updatedAt: 0,
          settings: {
            providerId: "ollama",
            activeModelByProvider: {
              ollama: "llava",
            },
            providerConnections: {
              ollama: {
                models: [
                  {
                    id: "llava",
                    vision: true,
                  },
                ],
              },
            },
          },
        },
        {},
      ),
    ).toBe(true);
  });

  it("prefers DIMCODE_STATE_DIR over DIMCODE_HOME for session blobs", () => {
    process.env.DIMCODE_HOME = "/tmp/dim-home";
    process.env.DIMCODE_STATE_DIR = "/tmp/explicit-state";

    expect(resolveBlobStateDir()).toBe("/tmp/explicit-state");
  });

  it("falls back to the user home when no env override is present", () => {
    delete process.env.DIMCODE_HOME;
    delete process.env.DIMCODE_STATE_DIR;

    expect(resolveDimcodeConfigDir({})).toBe(path.resolve(homedir(), ".dimcode"));
    expect(resolveBlobStateDir()).toBe(path.resolve(homedir(), ".dimcode", "state"));
  });
});
