import { v as TelemetryAttributes, M as MetricNamespace, d as TelemetryNamespace, j as APPLICATION_VERSION, m as mapUnknownToErrorType, i as isAbortError, a as isBlockedAccessError, w as getMachineId, g as getContentCollectionOptIn, o as getUserCohort } from "../../errors-B0mWE-BL.js";
import { C, k, n } from "../../errors-B0mWE-BL.js";
import * as vscode from "vscode";
import * as os from "os";
import * as semver from "semver";
import { propagation, context, trace, metrics, SpanStatusCode } from "@opentelemetry/api";
import "path";
import "fs";
import "node-machine-id";
class ContextPropagation {
  /**
   * Gets a context value from the current context
   * @param key The key for the context value
   * @returns The value or undefined if not found
   */
  static getContextValue(key) {
    const baggage = propagation.getBaggage(context.active());
    if (!baggage) {
      return void 0;
    }
    const entry = baggage.getEntry(key);
    return entry?.value;
  }
  /**
   * Executes a function with the given context values
   * @param contextValues The context values to set
   * @param fn The function to execute
   * @returns The result of the function
   */
  static withContextValues(contextValues, fn) {
    const baggage = propagation.getBaggage(context.active()) || propagation.createBaggage();
    let updatedBaggage = baggage;
    for (const [key, value] of Object.entries(contextValues)) {
      updatedBaggage = updatedBaggage.setEntry(key, { value });
    }
    const updatedContext = propagation.setBaggage(context.active(), updatedBaggage);
    return context.with(updatedContext, () => {
      const currentSpan = trace.getActiveSpan();
      if (currentSpan) {
        for (const [key, value] of Object.entries(contextValues)) {
          currentSpan.setAttribute(key, value);
        }
      }
      return fn();
    });
  }
  /**
   * Creates attributes object with all current context values
   * @returns Attributes object with context values and additional attributes
   */
  static getTelemetryAttributes() {
    const attributes = {};
    const baggage = propagation.getBaggage(context.active());
    if (baggage) {
      baggage.getAllEntries().forEach(([key, entry]) => {
        if (Object.values(TelemetryAttributes).includes(key)) {
          attributes[key] = entry.value;
        }
      });
    }
    const activeSpan = trace.getActiveSpan();
    if (activeSpan) {
      attributes[TelemetryAttributes.XRayTraceId] = `${activeSpan.spanContext().traceId}@${activeSpan.spanContext().spanId}`;
    }
    return attributes;
  }
}
function wrapCallback(props) {
  return function(...args) {
    let isPromise = false;
    const startTime = performance.now();
    try {
      props.before?.();
      const result = props.callback.apply(this, args);
      if (result instanceof Promise) {
        isPromise = true;
        return result.then((result2) => {
          props.success?.();
          return result2;
        }).catch((error) => {
          props.failure?.(error);
          throw error;
        }).finally(() => {
          props.after?.(performance.now() - startTime);
        });
      }
      props.success?.();
      return result;
    } catch (error) {
      props.failure?.(error);
      throw error;
    } finally {
      if (!isPromise) {
        props.after?.(performance.now() - startTime);
      }
    }
  };
}
const PERIODIC_RATE = 1e3 * 60 * 15;
class MetricReporter {
  static periodicReporters = /* @__PURE__ */ new Map();
  static periodicReporterTimeout;
  namespace;
  scope;
  constructor(namespace, scope) {
    this.namespace = namespace;
    this.scope = scope;
  }
  extendScope(value) {
    return this.scope ? `${this.scope}.${value}` : value;
  }
  static toNumber(value) {
    if (typeof value === "boolean") {
      return value ? 1 : 0;
    }
    return value;
  }
  getOperationTrackers(metricName, errorType) {
    const completeName = this.extendScope(metricName);
    const meter = metrics.getMeterProvider().getMeter(this.namespace);
    return {
      abort: meter.createCounter(`${completeName}.abort`, { unit: "number" }),
      abandon: meter.createCounter(`${completeName}.abandon`, { unit: "number" }),
      badInput: meter.createCounter(`${completeName}.badInput`, { unit: "number" }),
      unauthorized: meter.createCounter(`${completeName}.unauthorized`, { unit: "number" }),
      count: meter.createCounter(`${completeName}.count`, { unit: "number" }),
      failure: meter.createCounter(`${completeName}.failure`, { unit: "number" }),
      blocked: meter.createCounter(`${completeName}.blocked`, { unit: "number" }),
      environmentIssue: meter.createCounter(`${completeName}.environmentIssue`, { unit: "number" }),
      errorType: meter.createCounter(`${completeName}.errorType.${errorType}`, { unit: "number" }),
      success: meter.createCounter(`${completeName}.success`, { unit: "number" }),
      latency: meter.createHistogram(`${completeName}.latency`, { unit: "ms" })
    };
  }
  static async handlePeriodicReporters() {
    const reporter = metrics.getMeterProvider().getMeter(MetricNamespace.Periodic);
    for (const [trackerName, handler] of this.periodicReporters) {
      const report = await handler();
      for (const metricName of Object.keys(report)) {
        const attributes = { ...getDefaultAttributes(), Periodic: trackerName };
        const fullName = `${trackerName}.${metricName}`;
        const value = this.toNumber(report[metricName]);
        if (value === void 0) {
          continue;
        }
        reporter.createHistogram(fullName, { unit: "number" }).record(value, attributes);
      }
    }
  }
  /**
   * Start the periodic metric reporter
   */
  static startPeriodicReporterLoop() {
    if (this.periodicReporterTimeout) {
      clearInterval(this.periodicReporterTimeout);
    }
    this.periodicReporterTimeout = setInterval(() => void this.handlePeriodicReporters(), PERIODIC_RATE);
  }
  /**
   * Reports metrics under a given scope with a histogram reporter
   */
  reportHistogramMetrics(metricReport, dimensions = {}) {
    const reporter = metrics.getMeterProvider().getMeter(this.namespace);
    const attributes = {
      ...getDefaultAttributes(),
      Operation: this.scope,
      ...dimensions,
      ...ContextPropagation.getTelemetryAttributes()
    };
    for (const metricName of Object.keys(metricReport)) {
      const fullName = this.extendScope(metricName);
      const value = MetricReporter.toNumber(metricReport[metricName]);
      if (value === void 0) {
        continue;
      }
      reporter.createHistogram(fullName).record(value, attributes);
    }
  }
  /**
   * Reports metrics under a given scope with a counter reporter
   */
  reportCountMetrics(metricReport, dimensions = {}) {
    const reporter = metrics.getMeterProvider().getMeter(this.namespace);
    const attributes = {
      ...getDefaultAttributes(),
      Operation: this.scope,
      ...ContextPropagation.getTelemetryAttributes(),
      ...dimensions
    };
    for (const metricName of Object.keys(metricReport)) {
      const fullName = this.extendScope(metricName);
      const value = MetricReporter.toNumber(metricReport[metricName]);
      if (value === void 0) {
        continue;
      }
      reporter.createCounter(fullName).add(value, attributes);
    }
  }
  /**
   * Wraps a function in metrics, creating a new function which will emit the given metrics
   */
  wrapMetrics(operationName, fn) {
    const getBaseAttributes = () => ({ ...getDefaultAttributes(), Operation: operationName });
    return wrapCallback({
      callback: fn,
      before: () => {
        const attributes = {
          ...getBaseAttributes(),
          ...ContextPropagation.getTelemetryAttributes()
        };
        this.getOperationTrackers(operationName).count.add(1, attributes);
      },
      success: () => {
        const attributes = {
          ...getBaseAttributes(),
          ...ContextPropagation.getTelemetryAttributes()
        };
        this.getOperationTrackers(operationName).success.add(1, attributes);
      },
      failure: (error) => {
        const errorType = mapUnknownToErrorType(error);
        const tracker = this.getOperationTrackers(operationName, errorType);
        const attributes = {
          ...getBaseAttributes(),
          ...ContextPropagation.getTelemetryAttributes()
        };
        const isAbort = isAbortError(error);
        const isBlocked = isBlockedAccessError(error);
        if (isAbort) {
          tracker.abort.add(1, { ...attributes, errorType });
          tracker.blocked.add(0, { ...attributes, errorType });
          tracker.failure.add(0, { ...attributes, errorType });
        } else if (isBlocked) {
          tracker.abort.add(0, { ...attributes, errorType });
          tracker.blocked.add(1, { ...attributes, errorType });
          tracker.failure.add(0, { ...attributes, errorType });
        } else {
          tracker.abort.add(0, { ...attributes, errorType });
          tracker.blocked.add(0, { ...attributes, errorType });
          tracker.failure.add(1, { ...attributes, errorType });
        }
        tracker.errorType.add(1, { ...attributes, errorType });
        tracker.success.add(0, attributes);
      },
      after: (duration) => {
        const attributes = {
          ...getBaseAttributes(),
          ...ContextPropagation.getTelemetryAttributes()
        };
        this.getOperationTrackers(operationName).latency.record(duration, attributes);
      }
    });
  }
  /**
   * Calls a function with metrics directly
   */
  callWithMetrics(operationName, fn) {
    return this.wrapMetrics(operationName, fn)();
  }
  /**
   * Sets up a periodic metric reporter with a given id
   */
  periodicallyCaptureMetrics(tracker) {
    MetricReporter.periodicReporters.set(this.scope || "default", tracker);
  }
  /**
   * Force the periodic metrics capture to run
   */
  forcePeriodicCapture() {
    void MetricReporter.handlePeriodicReporters();
  }
  /**
   * Decorator to handle adding metrics to a function
   */
  Metric(operationName) {
    const wrapper = this.wrapMetrics.bind(this);
    return function(_, propertyKey, descriptor) {
      const original = descriptor.value;
      const functionName = typeof propertyKey === "string" ? propertyKey : String(propertyKey);
      const metricName = operationName || functionName;
      const newFunction = wrapper(metricName, original);
      descriptor.value = newFunction;
    };
  }
  /**
   * Wraps a function in a trace, creating a new function which will emit x-ray traces
   */
  wrapTrace(traceName, fn, getAdditionalDimensions) {
    const fullTraceName = `${this.scope}.${traceName}`;
    const tracer = trace.getTracer(TelemetryNamespace.Application, APPLICATION_VERSION);
    const trackers = this.getOperationTrackers.bind(this);
    return function(...args) {
      const bound = () => fn.apply(this, args);
      const baseAttributes = { ...getDefaultAttributes(), Operation: traceName };
      return tracer.startActiveSpan(fullTraceName, (span) => {
        const handler = wrapCallback({
          callback: bound,
          before: () => {
            const attributes = {
              ...baseAttributes,
              ...ContextPropagation.getTelemetryAttributes(),
              ...getAdditionalDimensions ? getAdditionalDimensions() : {}
            };
            span.setAttributes(baseAttributes);
            trackers(traceName).count.add(1, attributes);
          },
          success: () => {
            span.setStatus({ code: SpanStatusCode.OK });
            const attributes = {
              ...baseAttributes,
              ...ContextPropagation.getTelemetryAttributes(),
              ...getAdditionalDimensions ? getAdditionalDimensions() : {}
            };
            trackers(traceName).success.add(1, attributes);
          },
          failure: (error) => {
            const errorType = mapUnknownToErrorType(error);
            const tracker = trackers(traceName, errorType);
            span.setStatus({ code: SpanStatusCode.ERROR, message: errorType });
            span.setAttribute("errorType", errorType);
            const attributes = {
              ...baseAttributes,
              ...ContextPropagation.getTelemetryAttributes(),
              ...getAdditionalDimensions ? getAdditionalDimensions() : {},
              errorType
            };
            const isAbort = isAbortError(error);
            const isBlocked = isBlockedAccessError(error);
            if (isAbort) {
              tracker.abort.add(1, { ...attributes, errorType });
              tracker.blocked.add(0, { ...attributes, errorType });
              tracker.failure.add(0, { ...attributes, errorType });
            } else if (isBlocked) {
              tracker.abort.add(0, { ...attributes, errorType });
              tracker.blocked.add(1, { ...attributes, errorType });
              tracker.failure.add(0, { ...attributes, errorType });
            } else {
              tracker.abort.add(0, { ...attributes, errorType });
              tracker.blocked.add(0, { ...attributes, errorType });
              tracker.failure.add(1, { ...attributes, errorType });
            }
            tracker.errorType.add(1, attributes);
            tracker.success.add(0, attributes);
          },
          after: (duration) => {
            const attributes = {
              ...baseAttributes,
              ...ContextPropagation.getTelemetryAttributes(),
              ...getAdditionalDimensions ? getAdditionalDimensions() : {}
            };
            trackers(traceName).latency.record(duration, attributes);
            span.end();
          }
        });
        return handler();
      });
    };
  }
  /**
   * Calls a function with trace directly
   */
  callWithTrace(traceName, fn) {
    return this.wrapTrace(traceName, fn)();
  }
  /**
   * Executes the callback function while emitting x-ray traces
   */
  withTrace({ traceName, metricAliases, errorMapper }, fn) {
    const baseAttributes = { ...getDefaultAttributes(), Operation: traceName };
    const fullTraceName = `${this.scope}.${traceName}`;
    const tracer = trace.getTracer(TelemetryNamespace.Application, APPLICATION_VERSION);
    const trackers = this.getOperationTrackers.bind(this);
    const metricNames = [traceName, ...metricAliases || []];
    const bound = (span) => fn.apply(this, [span]);
    return tracer.startActiveSpan(fullTraceName, (span) => {
      const handler = wrapCallback({
        callback: () => bound(span),
        before: () => {
          const attributes = {
            ...baseAttributes,
            ...ContextPropagation.getTelemetryAttributes()
          };
          span.setAttributes(baseAttributes);
          metricNames.forEach((metricName) => {
            const metricAttributes = { ...attributes, Operation: metricName };
            trackers(metricName).count.add(1, metricAttributes);
          });
        },
        success: () => {
          span.setStatus({ code: SpanStatusCode.OK });
          const attributes = {
            ...baseAttributes,
            ...ContextPropagation.getTelemetryAttributes()
          };
          metricNames.forEach((metricName) => {
            const metricAttributes = { ...attributes, Operation: metricName };
            trackers(metricName).success.add(1, metricAttributes);
          });
        },
        failure: (error) => {
          const errorType = mapUnknownToErrorType(error);
          const trackerList = metricNames.map((metricName) => ({
            tracker: trackers(metricName, errorType),
            metricName
          }));
          span.setStatus({ code: SpanStatusCode.ERROR, message: errorType });
          span.setAttribute("errorType", errorType);
          const attributes = {
            ...baseAttributes,
            ...ContextPropagation.getTelemetryAttributes(),
            errorType
          };
          const errorCounts = errorMapper(error);
          Object.keys(errorCounts).forEach((errorType2) => {
            trackerList.forEach(({ tracker, metricName }) => {
              const metricAttributes = { ...attributes, Operation: metricName, errorType: errorType2 };
              tracker[errorType2].add(errorCounts[errorType2], metricAttributes);
            });
          });
          trackerList.forEach(({ tracker, metricName }) => {
            const metricAttributes = { ...attributes, Operation: metricName };
            tracker.errorType.add(1, metricAttributes);
            tracker.success.add(0, metricAttributes);
          });
        },
        after: (duration) => {
          const attributes = {
            ...baseAttributes,
            ...ContextPropagation.getTelemetryAttributes()
          };
          metricNames.forEach((metricName) => {
            const metricAttributes = { ...attributes, Operation: metricName };
            trackers(metricName).latency.record(duration, metricAttributes);
          });
          span.end();
        }
      });
      return handler();
    });
  }
  /**
   * Sets up trace which can be closed when needed, not tied to a scope
   */
  createTrace(traceName) {
    const attributes = { ...getDefaultAttributes(), Operation: traceName };
    const fullTraceName = `${this.scope}.${traceName}`;
    const tracer = trace.getTracer(TelemetryNamespace.Application, APPLICATION_VERSION);
    let span = void 0;
    return {
      start: () => {
        span = tracer.startSpan(fullTraceName, { attributes });
      },
      success: () => {
        if (span) {
          span.setStatus({ code: SpanStatusCode.OK });
          span.end();
        }
      },
      fail: (error) => {
        if (span) {
          const errorType = mapUnknownToErrorType(error);
          span.setStatus({ code: SpanStatusCode.ERROR, message: errorType });
          span.end();
        }
      },
      setAttributes: (attributes2) => {
        if (span) {
          span.setAttributes(attributes2);
        }
      }
    };
  }
  /**
   * Decorator to handle adding traces to a function
   */
  Trace(operationName, getAdditionalDimensions) {
    const wrapper = this.wrapTrace.bind(this);
    return function(_, propertyKey, descriptor) {
      const original = descriptor.value;
      const functionName = typeof propertyKey === "string" ? propertyKey : String(propertyKey);
      const metricName = operationName || functionName;
      const newFunction = wrapper(metricName, original, getAdditionalDimensions);
      descriptor.value = newFunction;
    };
  }
}
let cachedUserId = "";
function getUserId() {
  return cachedUserId;
}
function setUserId(userId) {
  cachedUserId = userId || "";
}
function clearUserId() {
  cachedUserId = "";
}
const peerDependencies = { "@kiro/agent": "0.36.8" };
const packageJson = {
  peerDependencies
};
const KasVersion = packageJson.peerDependencies["@kiro/agent"];
const machineId = getMachineId();
const platform = `${os.platform()}-${os.release()}`;
const version = vscode.kiroVersion ?? "0.0.0";
const semanticVersion = semver.parse(version);
const channel = version.split("-").length === 1 ? "stable" : "insider";
const KiroClientVersion = `${semanticVersion?.major}.${semanticVersion?.minor}`;
const KiroClientVersionStr = `${semanticVersion?.major}-${semanticVersion?.minor}`;
const PlatformUsage = new MetricReporter(TelemetryNamespace.Application);
function getAutonomyMode() {
  try {
    return vscode.workspace.getConfiguration("kiroAgent").get("agentAutonomy") ?? "Autopilot";
  } catch {
    return "Autopilot";
  }
}
function getDefaultAttributes() {
  const userId = getUserId();
  return {
    KiroClientVersion,
    machineId,
    userId,
    platform,
    channel,
    version,
    KasVersion,
    ClientType: "kiro-ide",
    agentMode: getAutonomyMode(),
    userCohort: getUserCohort(),
    isContentCollectionOptIn: String(getContentCollectionOptIn())
  };
}
function periodicAttributes() {
  PlatformUsage.reportCountMetrics({ osPlatform: 1 }, { Operation: os.platform() });
  PlatformUsage.reportCountMetrics({ kiroChannel: 1 }, { Operation: channel });
  return {
    [`AppPlatform.${os.platform()}`]: true,
    [`AppVersion.${KiroClientVersionStr}`]: true
  };
}
const FeatureMetrics = new MetricReporter(TelemetryNamespace.Feature, "features");
let recentlyUsedFeatures = /* @__PURE__ */ new Set();
FeatureMetrics.periodicallyCaptureMetrics(() => {
  const resultMetrics = {};
  for (const feature of recentlyUsedFeatures) {
    resultMetrics[`${feature}.usedByUser`] = true;
  }
  if (recentlyUsedFeatures.size > 0) {
    resultMetrics[`anyAIFeaturesUsed`] = true;
  }
  recentlyUsedFeatures = /* @__PURE__ */ new Set();
  return resultMetrics;
});
function reportUsage(feature) {
  FeatureMetrics.reportCountMetrics({ [`${feature}.used`]: true });
  recentlyUsedFeatures.add(feature);
}
const Telemetry = new MetricReporter(TelemetryNamespace.Application);
Telemetry.periodicallyCaptureMetrics(() => periodicAttributes());
const Feature = {
  reportUsage
};
export {
  ContextPropagation as C,
  C as CONTENT_COLLECTION_KEY,
  k as CONTENT_COLLECTION_SECTION,
  Feature,
  MetricReporter,
  Telemetry,
  getDefaultAttributes as a,
  clearUserId as c,
  n as deriveUserCohort,
  getUserId as g,
  getContentCollectionOptIn,
  getUserCohort,
  setUserId as s
};
