"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const names_1 = require("./names");
function timedMatrixClientFunctionCall() {
    return function (target, propertyKey, descriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = function (...args) {
            const metrics = this.metrics;
            const context = metrics.assignUniqueContextId({ functionName: propertyKey });
            metrics.start(names_1.METRIC_MATRIX_CLIENT_FUNCTION_CALL, context);
            let result;
            let exception;
            try {
                result = originalMethod.apply(this, args);
            }
            catch (e) {
                exception = e;
                result = Promise.reject(e);
            }
            let promise = result;
            if (!(result instanceof Promise) && result !== null && result !== undefined) {
                promise = Promise.resolve(result);
            }
            promise
                .catch(() => metrics.increment(names_1.METRIC_MATRIX_CLIENT_FAILED_FUNCTION_CALL, context, 1))
                .then(() => metrics.increment(names_1.METRIC_MATRIX_CLIENT_SUCCESSFUL_FUNCTION_CALL, context, 1))
                .finally(() => metrics.end(names_1.METRIC_MATRIX_CLIENT_FUNCTION_CALL, context));
            if (exception)
                throw exception;
            return result;
        };
    };
}
exports.timedMatrixClientFunctionCall = timedMatrixClientFunctionCall;
