import { describe, test, afterEach } from "node:test";
import assert from "node:assert/strict";
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, existsSync } from "node:fs";
import { join, resolve } from "node:path";
import { tmpdir } from "node:os";
import { getAnalyticsRoot, findPluginRoot } from "../src/utils/storage.js";

// Regression lock for the fresh-clone / foreign-CWD analytics root resolution.
// The root must anchor on the .claude-plugin/plugin.json marker (correct by
// construction), NOT on a fragile count of "../" segments that silently breaks
// if the source layout is ever moved.
describe("analytics root resolution", () => {
  let tempDir: string | undefined;
  const savedEnv = process.env.ANALYTICS_ROOT;

  afterEach(() => {
    if (tempDir && existsSync(tempDir)) {
      rmSync(tempDir, { recursive: true, force: true });
    }
    tempDir = undefined;
    if (savedEnv === undefined) {
      delete process.env.ANALYTICS_ROOT;
    } else {
      process.env.ANALYTICS_ROOT = savedEnv;
    }
  });

  describe("findPluginRoot", () => {
    test("walks up to the directory containing .claude-plugin/plugin.json", () => {
      tempDir = mkdtempSync(join(tmpdir(), "plugin-root-"));
      mkdirSync(join(tempDir, ".claude-plugin"), { recursive: true });
      writeFileSync(join(tempDir, ".claude-plugin", "plugin.json"), "{}");
      // Mimic the real depth: scripts/analytics/src/utils
      const start = join(tempDir, "scripts", "analytics", "src", "utils");
      mkdirSync(start, { recursive: true });

      assert.equal(findPluginRoot(start), tempDir);
    });

    test("returns null when no marker exists up-tree", () => {
      tempDir = mkdtempSync(join(tmpdir(), "no-marker-"));
      const start = join(tempDir, "a", "b", "c");
      mkdirSync(start, { recursive: true });

      assert.equal(findPluginRoot(start), null);
    });
  });

  describe("getAnalyticsRoot", () => {
    test("honors ANALYTICS_ROOT override (resolved env path)", () => {
      tempDir = mkdtempSync(join(tmpdir(), "analytics-root-"));
      process.env.ANALYTICS_ROOT = tempDir;

      assert.equal(getAnalyticsRoot(), resolve(tempDir));
    });

    test("default (no env) anchors on the plugin dir, not scripts/analytics/assets", () => {
      delete process.env.ANALYTICS_ROOT;

      const root = getAnalyticsRoot();
      const suffix = join("assets", "analytics");
      assert.ok(root.endsWith(suffix), `expected to end with ${suffix}, got ${root}`);

      // The parent of assets/analytics must be the real plugin root (holds the marker),
      // proving the root is NOT scripts/analytics/assets/analytics.
      const pluginRoot = root.slice(0, root.length - (suffix.length + 1));
      assert.ok(
        existsSync(join(pluginRoot, ".claude-plugin", "plugin.json")),
        `plugin marker missing under resolved root parent: ${pluginRoot}`,
      );
      assert.ok(
        !pluginRoot.endsWith(join("scripts", "analytics")),
        `root wrongly anchored under scripts/analytics: ${pluginRoot}`,
      );
    });
  });
});
