function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/*
 * 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 class Reporter {
  constructor(config) {
    _defineProperty(this, "checkInterval", void 0);
    _defineProperty(this, "interval", void 0);
    _defineProperty(this, "lastAppId", void 0);
    _defineProperty(this, "http", 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 = wrapArray(eventNames).map(eventName => {
        this.log(`${type} Metric -> (${appName}:${eventName}):`);
        const report = createUiStatsMetric({
          type,
          appName,
          eventName,
          count
        });
        this.log(report);
        return report;
      });
      this.saveToReport(metrics);
    });
    _defineProperty(this, "reportUserAgent", appName => {
      this.log(`Reporting user-agent.`);
      const report = 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 !== ReportManager.REPORT_VERSION;
          if (versionMismatch || this.retryCount > this.maxRetries) {
            this.flushReport();
          }
        }
      }
      this.start();
    });
    const {
      http,
      storage,
      debug,
      checkInterval = 90000,
      storageKey = 'analytics'
    } = config;
    this.http = http;
    this.checkInterval = checkInterval;
    this.applicationUsage = new ApplicationUsage();
    this.storageManager = new ReportStorageManager(storageKey, storage);
    const storedReport = this.storageManager.get();
    this.reportManager = new 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]);
  }
}