import Telemetry from "../Telemetry";
import { SpanStatusCode } from "@opentelemetry/api";
import JSONFunctions from "../../../Types/JSONFunctions";
import { DisableTelemetry } from "../../EnvironmentConfig";
function CaptureSpan(data) {
    return function (target, propertyKey, descriptor) {
        var _a;
        const originalMethod = descriptor.value;
        let className = (_a = target === null || target === void 0 ? void 0 : target.constructor) === null || _a === void 0 ? void 0 : _a.name;
        if (className === "" || className === "Function") {
            const staticClassName = target === null || target === void 0 ? void 0 : target.name;
            if (staticClassName) {
                className = staticClassName;
            }
        }
        if (!className) {
            className = "UnknownClass";
        }
        const name = (data === null || data === void 0 ? void 0 : data.name) || `${className}.${propertyKey}`;
        descriptor.value = function (...args) {
            if (DisableTelemetry) {
                return originalMethod.apply(this, args);
            }
            let functionArguments = {};
            if (data === null || data === void 0 ? void 0 : data.captureArguments) {
                functionArguments = args.reduce((acc, arg, index) => {
                    acc[`arg${index}`] = arg;
                    return acc;
                }, {});
            }
            const spanAttributes = JSONFunctions.flattenObject(Object.assign(Object.assign({}, functionArguments), data === null || data === void 0 ? void 0 : data.attributes));
            return Telemetry.startActiveSpan({
                name: name,
                options: {
                    attributes: Object.assign({}, spanAttributes),
                },
                fn: (span) => {
                    let result = null;
                    try {
                        result = originalMethod.apply(this, args);
                        if (result instanceof Promise) {
                            return result
                                .then((res) => {
                                span.setStatus({
                                    code: SpanStatusCode.OK,
                                });
                                return res;
                            })
                                .catch((err) => {
                                Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
                                    span,
                                    exception: err,
                                });
                                throw err;
                            })
                                .finally(() => {
                                span.end();
                            });
                        }
                        span.setStatus({
                            code: SpanStatusCode.OK,
                        });
                        return result;
                    }
                    catch (err) {
                        Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
                            span,
                            exception: err,
                        });
                        throw err;
                    }
                    finally {
                        if (!(result instanceof Promise)) {
                            span.end();
                        }
                    }
                },
            });
        };
        return descriptor;
    };
}
export default CaptureSpan;
//# sourceMappingURL=CaptureSpan.js.map