/**
 * Unit tests for collection config path resolution (PR #190).
 *
 * Tests that getConfigDir() respects XDG_CONFIG_HOME, QMD_CONFIG_DIR,
 * and falls back to ~/.config/qmd.
 */

import { describe, test, expect, beforeEach, afterEach } from "vitest";
import { join } from "path";
import { homedir, tmpdir } from "os";
import { mkdtempSync, rmSync, readFileSync } from "fs";
import {
  getConfigPath,
  setConfigIndexName,
  setConfigSource,
  loadConfig,
  saveConfig,
} from "../src/collections.js";
import type { CollectionConfig } from "../src/collections.js";

// Save/restore env vars around each test
let savedEnv: Record<string, string | undefined>;

beforeEach(() => {
  savedEnv = {
    QMD_CONFIG_DIR: process.env.QMD_CONFIG_DIR,
    XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
  };
  // Reset index name to default
  setConfigIndexName("index");
});

afterEach(() => {
  // Reset index name to default (prevents leaking into other test files under bun test)
  setConfigIndexName("index");
  for (const [key, val] of Object.entries(savedEnv)) {
    if (val === undefined) {
      delete process.env[key];
    } else {
      process.env[key] = val;
    }
  }
});

describe("getConfigDir via getConfigPath", () => {
  test("defaults to ~/.config/qmd when no env vars are set", () => {
    delete process.env.QMD_CONFIG_DIR;
    delete process.env.XDG_CONFIG_HOME;
    expect(getConfigPath()).toBe(join(homedir(), ".config", "qmd", "index.yml"));
  });

  test("QMD_CONFIG_DIR takes highest priority", () => {
    process.env.QMD_CONFIG_DIR = "/custom/qmd-config";
    process.env.XDG_CONFIG_HOME = "/xdg/config";
    expect(getConfigPath()).toBe(join("/custom/qmd-config", "index.yml"));
  });

  test("XDG_CONFIG_HOME is used when QMD_CONFIG_DIR is not set", () => {
    delete process.env.QMD_CONFIG_DIR;
    process.env.XDG_CONFIG_HOME = "/xdg/config";
    expect(getConfigPath()).toBe(join("/xdg/config", "qmd", "index.yml"));
  });

  test("XDG_CONFIG_HOME appends qmd subdirectory", () => {
    delete process.env.QMD_CONFIG_DIR;
    process.env.XDG_CONFIG_HOME = "/home/agent/.config";
    expect(getConfigPath()).toBe(join("/home/agent/.config", "qmd", "index.yml"));
  });

  test("QMD_CONFIG_DIR overrides XDG_CONFIG_HOME", () => {
    process.env.QMD_CONFIG_DIR = "/override";
    process.env.XDG_CONFIG_HOME = "/should-not-use";
    expect(getConfigPath()).toBe(join("/override", "index.yml"));
  });

  test("respects custom index name", () => {
    delete process.env.QMD_CONFIG_DIR;
    process.env.XDG_CONFIG_HOME = "/xdg/config";
    setConfigIndexName("myindex");
    expect(getConfigPath()).toBe(join("/xdg/config", "qmd", "myindex.yml"));
  });
});

// ============================================================================
// chunkStrategy schema round-trip (Phase 2 — i-bud0h8vu)
// ============================================================================

describe("Collection.chunkStrategy YAML round-trip", () => {
  let tmpDir: string;

  beforeEach(() => {
    tmpDir = mkdtempSync(join(tmpdir(), "qmd-chunkstrategy-"));
    process.env.QMD_CONFIG_DIR = tmpDir;
    setConfigIndexName("index");
  });

  afterEach(() => {
    // Reset config source so we don't leak inline state
    setConfigSource();
    try {
      rmSync(tmpDir, { recursive: true, force: true });
    } catch {
      // best-effort
    }
  });

  test("chunkStrategy field persists through save/load cycle", () => {
    const config: CollectionConfig = {
      collections: {
        "oivo-cli": {
          path: "/srv/cli/src",
          pattern: "**/*.ts",
          chunkStrategy: "function",
        },
        "oivo-docs": {
          path: "/srv/docs",
          pattern: "**/*.md",
          // no chunkStrategy — should remain unset after round-trip
        },
      },
    };
    saveConfig(config);

    const loaded = loadConfig();
    expect(loaded.collections["oivo-cli"]?.chunkStrategy).toBe("function");
    expect(loaded.collections["oivo-docs"]?.chunkStrategy).toBeUndefined();
  });

  test("chunkStrategy 'auto' and 'regex' round-trip", () => {
    const config: CollectionConfig = {
      collections: {
        a: { path: "/a", pattern: "*.ts", chunkStrategy: "auto" },
        b: { path: "/b", pattern: "*.ts", chunkStrategy: "regex" },
      },
    };
    saveConfig(config);

    const loaded = loadConfig();
    expect(loaded.collections.a?.chunkStrategy).toBe("auto");
    expect(loaded.collections.b?.chunkStrategy).toBe("regex");
  });

  test("omitted chunkStrategy does not appear in serialized YAML", () => {
    const config: CollectionConfig = {
      collections: {
        plain: { path: "/p", pattern: "*.md" },
      },
    };
    saveConfig(config);

    const yaml = readFileSync(join(tmpDir, "index.yml"), "utf-8");
    expect(yaml).not.toContain("chunkStrategy");
  });
});
