import FeatureFlagsMap from './feature-flags-map';
import { LogUtility } from '../../utils/log';
import VegaTelemetryRuntimeMetricsManager from '@heartlandone/vega-sandbox-pr-2872-b08ecf441325d54aeb57d51d0ee39c8e6e6ac495-telemetry-runtime-metrics/index';
/**
 * Feature flag controller to manage feature flags.
 *
 * @class FeatureFlag
 * @property {Set<FeatureFlagKey>} enabledFeatureFlagKeySet - Set of feature flags that are enabled.
 */
class FeatureFlagController {
  /**
   * During constructor, It enables all the feature flags given by {@link FeatureFlagsMap} expect default disabled flags.
   */
  constructor() {
    this.enabledFeatureFlagKeySet = new Set();
    this.init();
  }
  /**
   * This function enables the feature flags with the given keys.
   *
   * @param {FeatureFlagKey[]} featureFlagKeys - The feature flags to enable.
   * @vegaVersion 1.3.0
   */
  enable(...featureFlagKeys) {
    featureFlagKeys.forEach((featureFlagKey) => {
      if (this.versionGuard(featureFlagKey)) {
        this.enabledFeatureFlagKeySet.add(featureFlagKey);
        this.sendFeatureFlagKeyToTelemetry(featureFlagKey, true);
      }
    });
  }
  /**
   * Disable the feature flags with the given keys.
   *
   * @param {FeatureFlagKey[]} featureFlagKeys - The feature flags to disable.
   * @vegaVersion 1.3.0
   */
  disable(...featureFlagKeys) {
    featureFlagKeys.forEach((featureFlagKey) => {
      if (this.versionGuard(featureFlagKey)) {
        this.enabledFeatureFlagKeySet.delete(featureFlagKey);
        this.sendFeatureFlagKeyToTelemetry(featureFlagKey, false);
      }
    });
  }
  /**
   * If the feature flag key is in the set of enabled feature flag keys, then return true, otherwise return false.
   *
   * @param {FeatureFlagKey} featureFlagKey - The feature flag key to check.
   * @returns {boolean} - True if the feature flag key is in the set of enabled feature flag keys, otherwise false.
   * @vegaVersion 1.3.0
   */
  isEnabled(featureFlagKey) {
    return this.enabledFeatureFlagKeySet.has(featureFlagKey);
  }
  /**
   * The `init` function initializes a set of enabled feature flags based on a map of feature flags,
   * excluding those disabled by default or removed.
   */
  init() {
    Object.keys(FeatureFlagsMap).map((flagKey) => {
      if (!FeatureFlagsMap[flagKey].disabledByDefault && !this.isRemoved(flagKey)) {
        this.enabledFeatureFlagKeySet.add(flagKey);
      }
    });
  }
  /**
   * Verify if the flag is valid
   *
   * @param {FeatureFlagKey} featureFlagKey - the feature flag key
   * @returns {boolean} return false and console error if the feature flag is removedAfterVersion is not empty
   */
  versionGuard(featureFlagKey) {
    if (this.isRemoved(featureFlagKey)) {
      LogUtility.error(`The feature flag key '${featureFlagKey}' has been removed after v${FeatureFlagsMap[featureFlagKey].removedAfterVersion}`);
      return false;
    }
    return true;
  }
  /**
   * Verify if the flag is removed or not
   *
   * @param {FeatureFlagKey} featureFlagKey - the feature flag key
   * @returns {boolean} return true if the feature flag removedAfterVersion is not empty
   */
  isRemoved(featureFlagKey) {
    return !!FeatureFlagsMap[featureFlagKey].removedAfterVersion;
  }
  /**
   * The function sends a feature flag key and its value to telemetry if a specific feature flag is
   * enabled.
   *
   * @param {FeatureFlagKey} featureFlagName - The `featureFlagName` parameter is a key that represents
   * a specific feature flag. It is used to identify and reference a particular feature
   * flag when checking its status or sending telemetry data related to it.
   * @param {boolean} featureFlagValue - The `featureFlagValue` parameter is a boolean value that
   * represents the value of a feature flag. It indicates whether the feature flag is enabled (`true`)
   * or disabled (`false`).
   */
  sendFeatureFlagKeyToTelemetry(featureFlagName, featureFlagValue) {
    if (this.canSendFeatureFlagsToTelemetry(featureFlagName, featureFlagValue)) {
      VegaTelemetryRuntimeMetricsManager.emit('featureFlagOverridden', {
        featureFlagName: featureFlagName,
        featureFlagOverriddenValue: featureFlagValue,
      });
    }
  }
  /**
   * The function `canSendFeatureFlagsToTelemetry` checks if a specific feature flag can be sent to
   * telemetry based on certain conditions.
   *
   * @param {FeatureFlagKey} featureFlagName - The `featureFlagName` parameter represents the key or
   * identifier of a feature flag. It is used to look up the corresponding feature flag in the
   * `FeatureFlagsMap` object.
   * @param {boolean} featureFlagValue - The `featureFlagValue` parameter in the
   * `canSendFeatureFlagsToTelemetry` function represents the value of a specific feature flag. It is a
   * boolean value that indicates whether the feature flag is enabled (`true`) or disabled (`false`).
   * @returns {boolean} The function `canSendFeatureFlagsToTelemetry` is returning a boolean value.
   */
  canSendFeatureFlagsToTelemetry(featureFlagName, featureFlagValue) {
    return !!FeatureFlagsMap[featureFlagName].disabledByDefault === featureFlagValue;
  }
}
export const FeatureFlag = new FeatureFlagController();
