import { describe, expect, test } from "bun:test";
import {
  HealthRegistry,
  ServiceContainer,
  memoryIdempotencyStore,
  serviceToken,
  withIdempotency,
} from "@wrnexus/core";
import { signal, watch } from "@wrnexus/reactive";
import { routeName } from "@wrnexus/router";
import { backoffDelay, retry, stableStringify } from "@wrnexus/helpers";
import { createDurableQueue } from "@wrnexus/queue";
import { PresenceChannel } from "@wrnexus/pubsub";
import { safeObjectKey, sniffContentType } from "@wrnexus/uploader";
import { auditWireTokens, contrast } from "@wrnexus/styles";
import { createPluginRunner, definePlugin, defaultClientRuntimePath } from "@wrnexus/plugin";
import { WRN_SYNTAX_VERSION, createSourceRange, sliceSource } from "@wrnexus/syntax";

describe("WRNexusJS 0.4 platform upgrades", () => {
  test("publishes the 0.4 syntax contract", () => {
    expect(WRN_SYNTAX_VERSION).toBe("0.4");
    expect(sliceSource("abcdef", createSourceRange(1, 4))).toBe("bcd");
  });

  test("supports scoped services and health checks", async () => {
    const token = serviceToken<{ name: string }>("example");
    const root = new ServiceContainer().set(token, { name: "root" });
    expect(root.scope().get(token).name).toBe("root");

    const health = new HealthRegistry();
    health.register("database", () => ({ status: "up" }));
    expect((await health.check()).status).toBe("up");
  });

  test("replays idempotent work", async () => {
    const store = memoryIdempotencyStore<number>();
    let executions = 0;
    const execute = async () => ++executions;
    expect((await withIdempotency(store, "request-1", execute)).replayed).toBe(false);
    expect((await withIdempotency(store, "request-1", execute)).replayed).toBe(true);
    expect(executions).toBe(1);
  });

  test("runs watchers with cleanup", () => {
    const value = signal(1);
    const seen: number[] = [];
    const stop = watch(
      () => value.get(),
      (next) => {
        seen.push(next);
      },
      { immediate: true },
    );
    value.set(2);
    stop();
    value.set(3);
    expect(seen).toEqual([1, 2]);
  });

  test("provides deterministic routing and resilience helpers", async () => {
    expect(routeName("/teams/[teamId]/members/[memberId]")).toBe("teams.teamId.members.memberId");
    expect(stableStringify({ b: 2, a: 1 })).toBe('{"a":1,"b":2}');
    expect(backoffDelay(1, { minDelayMs: 10, jitter: 0 })).toBe(10);

    let attempts = 0;
    const result = await retry(
      async () => {
        attempts++;
        if (attempts < 2) throw new Error("retry");
        return "ok";
      },
      { attempts: 2, minDelayMs: 0, jitter: 0 },
    );
    expect(result).toBe("ok");
  });

  test("drains durable jobs and tracks presence", async () => {
    const queue = createDurableQueue({ now: () => 100 });
    const output: number[] = [];
    queue.process<number>("number", async (job) => {
      output.push(job.data);
    });
    await queue.add("number", 7);
    expect(await queue.drain()).toBe(1);
    expect(output).toEqual([7]);

    let now = 1;
    const presence = new PresenceChannel(10, () => now);
    presence.touch("user-1");
    expect(presence.list()).toHaveLength(1);
    now = 12;
    expect(presence.list()).toHaveLength(0);
  });

  test("audits uploads and styles", () => {
    expect(safeObjectKey("../My Report.pdf", "docs")).toMatch(/^docs\//);
    expect(sniffContentType(new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))).toBe(
      "image/png",
    );
    expect(auditWireTokens(":root{--wire-a:#fff}.x{color:var(--wire-b)}").missing).toEqual([
      "--wire-b",
    ]);
    expect(contrast("#000", "#fff")?.level).toBe("aaa");
  });

  test("normalizes and validates package runtimes", async () => {
    expect(defaultClientRuntimePath("captcha")).toBe("/__wrnexus/assets/captcha.js");
    const runner = createPluginRunner(
      definePlugin({
        name: "test-runtime",
        clientRuntimes: [{ id: "test", source: "window.test=true" }],
      }),
      {
        root: process.cwd(),
        mode: "development",
        command: "test",
        metadata: new Map(),
        warn: () => {},
      },
    );
    const contributions = await runner.contributions();
    expect(contributions.clientRuntimes[0]?.publicPath).toBe("/__wrnexus/assets/test.js");
  });
});
