"use strict";

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

var _util = require("./util");

var _metrics = require("./metrics");

var _storage = require("./storage");

var _report = require("./report");

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; }

class Reporter {
  // private http: ReportHTTP;
  constructor(config) {
    _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", () => {
      if (!this.interval) {
        this.interval = setTimeout(() => {
          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', () => 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', () => {
          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", (appName, type, eventNames, count) => {
      const metrics = (0, _util.wrapArray)(eventNames).map(eventName => {
        this.log(`${type} Metric -> (${appName}:${eventName}):`);
        const report = (0, _metrics.createUiStatsMetric)({
          type,
          appName,
          eventName,
          count
        });
        this.log(report);
        return report;
      });
      this.saveToReport(metrics);
    });

    _defineProperty(this, "reportUserAgent", appName => {
      this.log(`Reporting user-agent.`);
      const report = (0, _metrics.trackUsageAgent)(appName);
      this.saveToReport([report]);
    });

    _defineProperty(this, "sendReports", async () => {
      if (!this.reportManager.isReportEmpty()) {
        try {
          // await this.http(this.reportManager.report);
          this.flushReport();
        } catch (err) {
          this.log(`Error Sending Metrics Report ${err}`);
          this.retryCount = this.retryCount + 1;
          const versionMismatch = this.reportManager.report.reportVersion !== _report.ReportManager.REPORT_VERSION;

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

      this.start();
    });

    const {
      storage,
      debug,
      checkInterval = 90000,
      storageKey = 'analytics'
    } = config; // this.http = http;

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

  saveToReport(newMetrics) {
    this.reportManager.assignReports(newMetrics);
    this.storageManager.store(this.reportManager.report);
  }

  flushReport() {
    this.retryCount = 0;
    this.reportManager.clearReport();
    this.storageManager.store(this.reportManager.report);
  }

  log(message) {
    if (this.debug) {
      // eslint-disable-next-line
      console.debug(message);
    }
  }

  reportApplicationUsage(appId) {
    this.log(`Reporting application changed to ${appId}`);
    this.lastAppId = appId || this.lastAppId; // const appChangedReport = this.applicationUsage.appChanged(appId);
    // if (appChangedReport) this.saveToReport([appChangedReport]);
  }

}

exports.Reporter = Reporter;