function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * The OpenSearch Contributors require contributions made to
 * this file be licensed under the Apache-2.0 license or a
 * compatible open source license.
 *
 * Any modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

/*
 * Licensed to Elasticsearch B.V. under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch B.V. licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { wrapArray } from './util';
import { createUiStatsMetric, trackUsageAgent } from './metrics';
import { ReportStorageManager } from './storage';
import { ReportManager } from './report';
import { ApplicationUsage } from './metrics';
export var Reporter = /*#__PURE__*/function () {
  // private http: ReportHTTP;
  function Reporter(config) {
    var _this = this;

    _classCallCheck(this, Reporter);

    _defineProperty(this, "checkInterval", void 0);

    _defineProperty(this, "interval", void 0);

    _defineProperty(this, "lastAppId", void 0);

    _defineProperty(this, "reportManager", void 0);

    _defineProperty(this, "storageManager", void 0);

    _defineProperty(this, "applicationUsage", void 0);

    _defineProperty(this, "debug", void 0);

    _defineProperty(this, "retryCount", 0);

    _defineProperty(this, "maxRetries", 3);

    _defineProperty(this, "started", false);

    _defineProperty(this, "start", function () {
      if (!_this.interval) {
        _this.interval = setTimeout(function () {
          _this.interval = undefined;

          _this.sendReports();
        }, _this.checkInterval);
      }

      if (_this.started) {
        return;
      }

      if (window && document) {
        // Before leaving the page, make sure we store the current usage
        window.addEventListener('beforeunload', function () {
          return _this.reportApplicationUsage();
        }); // Monitoring dashboards might be open in background and we are fine with that
        // but we don't want to report hours if the user goes to another tab and OpenSearch Dashboards is not shown

        document.addEventListener('visibilitychange', function () {
          if (document.visibilityState === 'visible' && _this.lastAppId) {
            _this.reportApplicationUsage(_this.lastAppId);
          } else if (document.visibilityState === 'hidden') {
            _this.reportApplicationUsage(); // We also want to send the report now because intervals and timeouts be stalled when too long in the "hidden" state


            _this.sendReports();
          }
        });
      }

      _this.started = true;

      _this.applicationUsage.start();
    });

    _defineProperty(this, "reportUiStats", function (appName, type, eventNames, count) {
      var metrics = wrapArray(eventNames).map(function (eventName) {
        _this.log("".concat(type, " Metric -> (").concat(appName, ":").concat(eventName, "):"));

        var report = createUiStatsMetric({
          type: type,
          appName: appName,
          eventName: eventName,
          count: count
        });

        _this.log(report);

        return report;
      });

      _this.saveToReport(metrics);
    });

    _defineProperty(this, "reportUserAgent", function (appName) {
      _this.log("Reporting user-agent.");

      var report = trackUsageAgent(appName);

      _this.saveToReport([report]);
    });

    _defineProperty(this, "sendReports", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
      var versionMismatch;
      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!_this.reportManager.isReportEmpty()) {
                try {
                  // await this.http(this.reportManager.report);
                  _this.flushReport();
                } catch (err) {
                  _this.log("Error Sending Metrics Report ".concat(err));

                  _this.retryCount = _this.retryCount + 1;
                  versionMismatch = _this.reportManager.report.reportVersion !== ReportManager.REPORT_VERSION;

                  if (versionMismatch || _this.retryCount > _this.maxRetries) {
                    _this.flushReport();
                  }
                }
              }

              _this.start();

            case 2:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    })));

    var storage = config.storage,
        debug = config.debug,
        _config$checkInterval = config.checkInterval,
        checkInterval = _config$checkInterval === void 0 ? 90000 : _config$checkInterval,
        _config$storageKey = config.storageKey,
        storageKey = _config$storageKey === void 0 ? 'analytics' : _config$storageKey; // this.http = http;

    this.checkInterval = checkInterval;
    this.applicationUsage = new ApplicationUsage();
    this.storageManager = new ReportStorageManager(storageKey, storage);
    var storedReport = this.storageManager.get();
    this.reportManager = new ReportManager(storedReport);
    this.debug = !!debug;
  }

  _createClass(Reporter, [{
    key: "saveToReport",
    value: function saveToReport(newMetrics) {
      this.reportManager.assignReports(newMetrics);
      this.storageManager.store(this.reportManager.report);
    }
  }, {
    key: "flushReport",
    value: function flushReport() {
      this.retryCount = 0;
      this.reportManager.clearReport();
      this.storageManager.store(this.reportManager.report);
    }
  }, {
    key: "log",
    value: function log(message) {
      if (this.debug) {
        // eslint-disable-next-line
        console.debug(message);
      }
    }
  }, {
    key: "reportApplicationUsage",
    value: function reportApplicationUsage(appId) {
      this.log("Reporting application changed to ".concat(appId));
      this.lastAppId = appId || this.lastAppId; // const appChangedReport = this.applicationUsage.appChanged(appId);
      // if (appChangedReport) this.saveToReport([appChangedReport]);
    }
  }]);

  return Reporter;
}();