import { afterAll, describe, expect, it, vi } from "vitest";

vi.setConfig({ testTimeout: 30_000 });
import { ESLint } from "eslint";
import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";

const ROOT = path.resolve(import.meta.dirname, "../..");
const eslint = new ESLint({ cwd: ROOT });

const probeFiles: string[] = [];

function uid(): string {
  return crypto.randomBytes(4).toString("hex");
}

afterAll(() => {
  for (const f of probeFiles) {
    try { fs.unlinkSync(f); } catch { /* ok */ }
    let dir = path.dirname(f);
    const srcDir = path.join(ROOT, "src");
    while (dir.length > srcDir.length) {
      try { fs.rmdirSync(dir); } catch { break; }
      dir = path.dirname(dir);
    }
  }
});

async function lintString(filePath: string, content: string): Promise<string> {
  const absPath = path.join(ROOT, filePath);
  fs.mkdirSync(path.dirname(absPath), { recursive: true });
  fs.writeFileSync(absPath, content, "utf8");
  probeFiles.push(absPath);

  const results = await eslint.lintFiles([absPath]);
  const messages = results.flatMap((r) => r.messages);

  if (messages.length === 0) return "PASS";
  return JSON.stringify(messages.map((m) => ({ ruleId: m.ruleId, message: m.message })));
}

describe("no-restricted-imports rules", () => {
  it("blocks @opentelemetry/sdk-metrics outside otel.ts", async () => {
    const id = uid();
    const result = await lintString(
      `src/features/online-board/__ri_probe_${id}__.ts`,
      'import { MeterProvider } from "@opentelemetry/sdk-metrics";\nexport const x = MeterProvider;\n',
    );
    expect(result).toContain("no-restricted-imports");
  });

  it("blocks react-i18next outside provider.tsx", async () => {
    const id = uid();
    const result = await lintString(
      `src/features/online-board/__ri_probe_${id}__.ts`,
      'import { useTranslation } from "react-i18next";\nexport const x = useTranslation;\n',
    );
    expect(result).toContain("no-restricted-imports");
  });

  it("blocks @microsoft/signalr in routes/ (SSR bundle)", async () => {
    const id = uid();
    const result = await lintString(
      `src/routes/__probe_${id}__/__ri_probe__.ts`,
      'import { HubConnectionBuilder } from "@microsoft/signalr";\nexport const x = HubConnectionBuilder;\n',
    );
    expect(result).toContain("no-restricted-imports");
  });

  it("blocks localStorage outside storage.ts", async () => {
    const id = uid();
    const result = await lintString(
      `src/features/online-board/__ri_probe_${id}__.ts`,
      'const x = localStorage.getItem("key");\nexport default x;\n',
    );
    expect(result).toContain("no-restricted-globals");
  });
});
