// packages/core-shared/src/instrumentation/di/bind-sentry-instrumentation.test.ts
import "reflect-metadata";
import { describe, it, expect, vi, beforeEach } from "vitest";

vi.mock("@sentry/nextjs", () => ({
  init: vi.fn(),
  startSpan: vi.fn((_opts: unknown, fn: (span: unknown) => unknown) =>
    fn({ setAttribute: vi.fn(), setStatus: vi.fn() }),
  ),
  captureException: vi.fn(),
  captureMessage: vi.fn(),
  addBreadcrumb: vi.fn(),
  setUser: vi.fn(),
  replayIntegration: vi.fn(() => ({ name: "Replay" })),
}));

import * as Sentry from "@sentry/nextjs";
import { Container } from "inversify";
import { bindSentryInstrumentation } from "@/instrumentation/di/bind-sentry-instrumentation";
import { INSTRUMENTATION_SYMBOLS } from "@/instrumentation/symbols";
import { SentryTracer } from "@/instrumentation/sentry/sentry-tracer";
import { SentryLogger } from "@/instrumentation/sentry/sentry-logger";

describe("bindSentryInstrumentation", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("calls Sentry.init via initSentryServer", () => {
    const c = new Container();
    bindSentryInstrumentation(c, { dsn: "https://x@y/1", app: "web-next" });
    expect(Sentry.init).toHaveBeenCalledTimes(1);
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    expect((Sentry.init as any).mock.calls[0][0].dsn).toBe("https://x@y/1");
  });

  it("binds SentryTracer + SentryLogger to the container", () => {
    const c = new Container();
    bindSentryInstrumentation(c, { dsn: "https://x@y/1", app: "web-next" });
    expect(c.get(INSTRUMENTATION_SYMBOLS.TRACER)).toBeInstanceOf(SentryTracer);
    expect(c.get(INSTRUMENTATION_SYMBOLS.LOGGER)).toBeInstanceOf(SentryLogger);
  });

  it("returns the tracer + logger instances", () => {
    const c = new Container();
    const { tracer, logger } = bindSentryInstrumentation(c, {
      dsn: "https://x@y/1",
      app: "web-next",
    });
    expect(tracer).toBeInstanceOf(SentryTracer);
    expect(logger).toBeInstanceOf(SentryLogger);
  });
});
