"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.time2CountWin = exports.getMetrics = exports.addToMetric = void 0;

var _lodash = _interopRequireDefault(require("lodash"));

var _constants = require("./constants");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */
const time2CountWin = new Map();
exports.time2CountWin = time2CountWin;

const addToMetric = (entity, action, counter, reportMetadata) => {
  const count = 1; // remove outdated key-value pairs

  trim();
  const timeKey = getKey(Date.now());
  const rollingCounters = time2CountWin.get(timeKey);
  time2CountWin.set(timeKey, updateCounters(entity, action, counter, rollingCounters || _lodash.default.cloneDeep(_constants.DEFAULT_ROLLING_COUNTER), count, reportMetadata));
};

exports.addToMetric = addToMetric;

const getMetrics = () => {
  const preTimeKey = getPreKey(Date.now());
  const rollingCounters = time2CountWin.get(preTimeKey);
  const metrics = buildMetrics(rollingCounters);
  return metrics;
};

exports.getMetrics = getMetrics;

const trim = () => {
  if (time2CountWin.size > _constants.CAPACITY) {
    const currentKey = getKey(Date.now() - _constants.WINDOW * 1000);
    time2CountWin.forEach((_value, key, map) => {
      if (key < currentKey) {
        map.delete(key);
      }
    });
  }
};

const getKey = milliseconds => {
  return Math.floor(milliseconds / 1000 / _constants.INTERVAL);
};

const getPreKey = milliseconds => {
  return getKey(milliseconds) - 1;
};

const isEntity = arg => {
  return arg === 'report' || arg === 'report_definition' || arg === 'report_source';
};

const buildMetrics = rollingCounters => {
  if (!rollingCounters) {
    rollingCounters = _constants.DEFAULT_ROLLING_COUNTER;
  }

  const basicMetrics = _lodash.default.merge(rollingCounters, _constants.GLOBAL_BASIC_COUNTER);

  const overallActionMetrics = {
    request_total: 0,
    request_count: 0,
    success_count: 0,
    failed_request_count_system_error: 0,
    failed_request_count_user_error: 0
  };
  Object.keys(basicMetrics).forEach(keys => {
    if (isEntity(keys)) {
      for (const [action, counters] of Object.entries(basicMetrics[keys])) {
        overallActionMetrics.request_count += (counters === null || counters === void 0 ? void 0 : counters.count) || 0;
        overallActionMetrics.request_total += (counters === null || counters === void 0 ? void 0 : counters.total) || 0;
        overallActionMetrics.failed_request_count_system_error += (counters === null || counters === void 0 ? void 0 : counters.system_error) || 0;
        overallActionMetrics.failed_request_count_user_error += (counters === null || counters === void 0 ? void 0 : counters.user_error) || 0;
      }
    }
  });
  overallActionMetrics.success_count = overallActionMetrics.request_count - (overallActionMetrics.failed_request_count_system_error + overallActionMetrics.failed_request_count_user_error);
  return { ...basicMetrics,
    ...overallActionMetrics
  };
};

const updateCounters = (entity, action, counter, rollingCounter, count, reportMetadata) => {
  // update usage metrics
  if (reportMetadata) {
    const {
      report_definition: {
        report_params: {
          report_source: source,
          core_params: {
            report_format: format
          }
        }
      }
    } = reportMetadata; // @ts-ignore

    rollingCounter[source.toLowerCase().replace(' ', '_')][format]['download'][counter] += count; // update basic counter for total request count

    if (counter === 'count') {
      //@ts-ignore
      _constants.GLOBAL_BASIC_COUNTER[source.toLowerCase().replace(' ', '_')][format]['download']['total']++;
    }
  } else {
    // update action metric, per API
    // @ts-ignore
    rollingCounter[entity][action][counter] += count;

    if (counter === 'count') {
      // @ts-ignore
      _constants.GLOBAL_BASIC_COUNTER[entity][action]['total']++;
    }
  }

  return rollingCounter;
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,[encoded data, 11216 characters]