Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

const instrumentation = require('@opentelemetry/instrumentation');
const core = require('@sentry/core');

const supportedVersions = ['>=0.10.0 <2'];

/**
 * Represents the patched shape of the Google GenAI module export.
 */

/**
 * Sentry Google GenAI instrumentation using OpenTelemetry.
 */
class SentryGoogleGenAiInstrumentation extends instrumentation.InstrumentationBase {
   constructor(config = {}) {
    super('@sentry/instrumentation-google-genai', core.SDK_VERSION, config);
  }

  /**
   * Initializes the instrumentation by defining the modules to be patched.
   */
   init() {
    const module = new instrumentation.InstrumentationNodeModuleDefinition(
      '@google/genai',
      supportedVersions,
      exports => this._patch(exports),
      exports => exports,
      // In CJS, @google/genai re-exports from (dist/node/index.cjs) file.
      // Patching only the root module sometimes misses the real implementation or
      // gets overwritten when that file is loaded. We add a file-level patch so that
      // _patch runs again on the concrete implementation
      [
        new instrumentation.InstrumentationNodeModuleFile(
          '@google/genai/dist/node/index.cjs',
          supportedVersions,
          exports => this._patch(exports),
          exports => exports,
        ),
      ],
    );
    return module;
  }

  /**
   * Core patch logic applying instrumentation to the Google GenAI client constructor.
   */
   _patch(exports) {
    const Original = exports.GoogleGenAI;
    const config = this.getConfig();

    if (typeof Original !== 'function') {
      return exports;
    }

    const WrappedGoogleGenAI = function ( ...args) {
      const instance = Reflect.construct(Original, args);
      const client = core.getClient();
      const defaultPii = Boolean(client?.getOptions().sendDefaultPii);

      const typedConfig = config;
      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
      const recordInputs = typedConfig?.recordInputs ?? defaultPii;
      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
      const recordOutputs = typedConfig?.recordOutputs ?? defaultPii;

      return core.instrumentGoogleGenAIClient(instance, {
        recordInputs,
        recordOutputs,
      });
    };

    // Preserve static and prototype chains
    Object.setPrototypeOf(WrappedGoogleGenAI, Original);
    Object.setPrototypeOf(WrappedGoogleGenAI.prototype, Original.prototype);

    for (const key of Object.getOwnPropertyNames(Original)) {
      if (!['length', 'name', 'prototype'].includes(key)) {
        const descriptor = Object.getOwnPropertyDescriptor(Original, key);
        if (descriptor) {
          Object.defineProperty(WrappedGoogleGenAI, key, descriptor);
        }
      }
    }

    // Replace google genai exports with the wrapped constructor
    core.replaceExports(exports, 'GoogleGenAI', WrappedGoogleGenAI);

    return exports;
  }
}

exports.SentryGoogleGenAiInstrumentation = SentryGoogleGenAiInstrumentation;
