import { CurrentlyInvokedMethodName, VegaSlimmer } from 'vega-slimmer/core';
import { LogUtility } from '../../../utils/log';
import { isObjectEmpty } from '../../../utils/misc';
/**
 * The `VegaPublicAPIRuntimeMetricsSlimmerBase` class is used for sending
 * telemetry data to a telemetry service based on defined usage metrics for a public api.
 */
export class VegaPublicAPIRuntimeMetricsSlimmerBase extends VegaSlimmer {
  /**
   * The constructor initializes a private readonly property with an optional array of
   * PublicAPIRuntimeMetricsDefinition.
   *
   * @param {string} [className] - The parameter show the class name of public api.
   * @param {PublicAPIRuntimeMetricsDefinition[]} [usageDefinitions] - The `usageDefinitions`
   * parameter in the constructor is of type `PublicAPIRuntimeMetricsDefinition<T>[]`, which is an
   * array of `ComponentUsageRuntimeMetricsDefinition` objects. This parameter is optional as it is
   * marked with a question mark `?`, meaning it can be omitted when creating an instance of
   */
  constructor(className, usageDefinitions) {
    super();
    this.className = className;
    this.usageDefinitions = usageDefinitions;
  }
  /**
   * register the observer when the slimmer method called
   *
   * @param {unknown[]} [args] - The `args` parameter passed in when the slimmer method is executed
   */
  sendPublicAPIPayloadToTelemetry(args) {
    try {
      const publicAPIMetricsPayload = this.getPublicAPIMetricsPayload(args);
      if (publicAPIMetricsPayload) {
        // eslint-disable-next-line spellcheck/spell-checker
        void import('@heartlandone/vega-telemetry-runtime-metrics/index').then((
        // eslint-disable-next-line spellcheck/spell-checker
        module) => {
          module['default']['emit']('publicAPIMetrics', publicAPIMetricsPayload);
        });
      }
    }
    catch (error) {
      LogUtility.log('Public API payload failed to emit telemetry:', error);
    }
  }
  /**
   * The function `getPublicAPIMetricsPayload` generates a payload containing public api
   * metrics data.
   * The `CurrentlyInvokedMethodName` is a public API method name, it comes from the `InjectVegaTelemetrySlimmer` definition and assignment
   *
   * @param {unknown[]} [args] - The `args` parameter passed in when the slimmer method is executed
   * @returns {Nullable<Record<string, unknown>>} The `getPublicAPIMetricsPayload` method returns an object with the following
   * structure:
   * {
   * 	publicAPIName: string, // The public api name
   * 	data: { // An object containing payload data with keys and boolean values
   * 		'waitForVegaRenderFinished': true,
   * }
   */
  getPublicAPIMetricsPayload(args) {
    const payloadData = {};
    this.usageDefinitions
      .filter((definitions) => definitions.canAccept(this.className, this[CurrentlyInvokedMethodName], args))
      .forEach((definitions) => {
      payloadData[definitions.payloadKey] = definitions.payloadValue(args);
    });
    if (isObjectEmpty(payloadData)) {
      return null;
    }
    return {
      publicAPIName: this.className,
      data: payloadData,
    };
  }
}
