"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.__tsfTypeAliases = exports.OtelState = void 0;
exports.isTelemetryInitialized = isTelemetryInitialized;
exports.isTracingInstalled = isTracingInstalled;
exports.getTracer = getTracer;
exports.getActiveSpan = getActiveSpan;
exports.getTraceContext = getTraceContext;
exports.disableActiveTrace = disableActiveTrace;
exports.withRemoteSpan = withRemoteSpan;
exports.withSpan = withSpan;
exports.withRootSpan = withRootSpan;
exports.withLinkedRootSpan = withLinkedRootSpan;
exports.setSpanAttributes = setSpanAttributes;
const tslib_1 = require("tslib");
const _a = tslib_1.__importStar(require("@zyno-io/ts-server-foundation/type-metadata-runtime"));
const types_1 = require("node:util/types");
const api_1 = require("@opentelemetry/api");
exports.OtelState = {
    initialized: false,
    tracer: undefined,
    tracerProvider: undefined,
    meterProvider: undefined,
    prometheusExporter: undefined,
    unregisterInstrumentations: undefined,
    metricsEndpointEnabled: false,
    metricsEndpointPreference: undefined,
    get installed() {
        return exports.OtelState.tracer !== undefined;
    }
};
function isTelemetryInitialized() {
    return exports.OtelState.initialized;
}
function isTracingInstalled() {
    return exports.OtelState.installed;
}
function getTracer() {
    return exports.OtelState.tracer;
}
function getActiveSpan() {
    return api_1.trace.getActiveSpan();
}
function getTraceContext() {
    return getActiveSpan()?.spanContext();
}
function disableActiveTrace() {
    const ctx = getTraceContext();
    if (ctx)
        ctx.traceFlags = 0;
}
function isError(error) {
    return error instanceof Error || (0, types_1.isNativeError)(error);
}
async function runInSpan(span, fn) {
    try {
        const result = await fn();
        span.setStatus({ code: api_1.SpanStatusCode.OK });
        return result;
    }
    catch (error) {
        span.recordException(isError(error) ? error : String(error));
        span.setStatus({
            code: api_1.SpanStatusCode.ERROR,
            message: isError(error) ? error.message : String(error)
        });
        throw error;
    }
    finally {
        span.end();
    }
}
function withRemoteSpan(name, spanInfo, attrs, fn) {
    if (!exports.OtelState.tracer)
        return Promise.resolve(fn());
    if (!spanInfo)
        return withSpan(name, attrs, fn);
    const context = parseSpanInfo(spanInfo);
    if (!context)
        return withSpan(name, attrs, fn);
    const parentContext = api_1.trace.setSpanContext(api_1.ROOT_CONTEXT, {
        ...context,
        traceFlags: context.traceFlags ?? 1,
        isRemote: true
    });
    return exports.OtelState.tracer.startActiveSpan(name, { attributes: attrs, kind: api_1.SpanKind.SERVER }, parentContext, span => runInSpan(span, fn));
}
function withSpan(name, attrsOrFn, fn) {
    const resolvedAttrs = typeof attrsOrFn === 'object' ? attrsOrFn : undefined;
    const resolvedFn = fn ?? attrsOrFn;
    if (!exports.OtelState.tracer)
        return Promise.resolve(resolvedFn());
    return exports.OtelState.tracer.startActiveSpan(name, { attributes: resolvedAttrs }, span => runInSpan(span, resolvedFn));
}
function withRootSpan(name, attrsOrFn, fn) {
    const resolvedAttrs = typeof attrsOrFn === 'object' ? attrsOrFn : undefined;
    const resolvedFn = fn ?? attrsOrFn;
    if (!exports.OtelState.tracer)
        return Promise.resolve(resolvedFn());
    return exports.OtelState.tracer.startActiveSpan(name, { attributes: resolvedAttrs }, api_1.ROOT_CONTEXT, span => runInSpan(span, resolvedFn));
}
function withLinkedRootSpan(name, links, attrs, fn) {
    if (!exports.OtelState.tracer)
        return Promise.resolve(fn());
    const otelLinks = links.map(link => ({
        context: {
            traceId: link.traceId,
            spanId: link.spanId,
            traceFlags: link.traceFlags ?? 1,
            isRemote: true
        },
        attributes: link.attributes
    }));
    return exports.OtelState.tracer.startActiveSpan(name, { attributes: attrs, links: otelLinks }, api_1.ROOT_CONTEXT, span => runInSpan(span, fn));
}
function setSpanAttributes(attributes) {
    if (!exports.OtelState.installed)
        return;
    getActiveSpan()?.setAttributes(attributes);
}
function parseSpanInfo(spanInfo) {
    if (!spanInfo)
        return undefined;
    if ('traceparent' in spanInfo) {
        const parts = spanInfo.traceparent.split('-');
        if (parts.length < 4 || parts[0] !== '00')
            return undefined;
        return {
            traceId: parts[1],
            spanId: parts[2],
            traceFlags: Number.parseInt(parts[3], 16)
        };
    }
    return spanInfo;
}
exports.__tsfTypeAliases = _a.decodeCompactMetadataV1("[1,{\"SpanInfo\":{\"kind\":12,\"types\":[{\"kind\":18,\"types\":[{\"kind\":20,\"name\":\"traceId\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"spanId\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"traceFlags\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true}]},{\"kind\":18,\"types\":[{\"kind\":20,\"name\":\"traceparent\",\"type\":{\"kind\":6},\"optional\":false}]},{\"kind\":4}],\"typeName\":\"SpanInfo\"},\"SpanLinkRef\":{\"kind\":18,\"types\":[{\"kind\":20,\"name\":\"traceId\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"spanId\",\"type\":{\"kind\":6},\"optional\":false},{\"kind\":20,\"name\":\"traceFlags\",\"type\":{\"kind\":12,\"types\":[{\"kind\":7},{\"kind\":4}]},\"optional\":true},{\"kind\":20,\"name\":\"attributes\",\"type\":{\"kind\":12,\"types\":[{\"$tsfAlias\":[0,\"@opentelemetry/api\",\"Attributes\",\"Attributes\"]},{\"kind\":4}]},\"optional\":true}],\"typeName\":\"SpanLinkRef\"}}]", [require]);
//# sourceMappingURL=helpers.js.map