// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ## How to use feature flags:
//
// - define a feature flag in `src/all-feature-flags.js`.
//   Check a few of the testing flags for examples
//
// - run `npm build`, which will *autogenerate* package.json configuration
//   for your flags.  You *DO NOT* edit package.json manually for this.
//
// - call `#enabled`:
//
//   ```
//   import * as features from './features';
//
//   if (features.enabled('myFeature')) { ... }
//   ```
//
//   Typescript will ensure you're only using defined flags
//
// ## How to name feature flags
//
// - use `camelCase` (this matches the vscode settings conventions)
// - use words that'd look good as a title, because they'll show up
//   like that in the vscode settings page.
//
//   For example, `showDevicePaneFromStatusBar` will become
//   `Show Device Pane From Status Bar` to users on the setting page.
//
// - avoid "new" and words like that (unless referencing an external
//   thing) -- anything new will be old one day, and then you'll
//   be stuck with `newNew` and then `newNewNew`.  Prefer versions
//   (e.g. `devicePicker2`) or just clear descriptions when possible.

import * as vscode from 'vscode';
import * as flags from './all-feature-flags';

/// the current base stability level -- will be autodetected
/// based on version number & config on #init, but can be overriden
/// with the `fuchsia.featurePreview` flag (can change at runtime).
let stabilityLevel: flags.Stability = 'stable';

/// the current default stability, as detected by the extension version
let defaultStability: flags.Stability = 'stable';

let watcher: vscode.Disposable;

/**
 * represents a change to one of the feature flags in this plugin
 */
export class FeatureFlagChangeEvent {
  private global;
  constructor(private original: vscode.ConfigurationChangeEvent, global?: boolean) {
    this.global = global ?? false;
  }

  /**
   * check if this change affects the given flag.
   *
   * It should never have false negatives, but it may have false positive in cases
   * of large-scale config changes.
   */
  affectsFlag(name: string): boolean {
    if (this.global) {
      // it'd be complicated to figure out which flags would've flipped, so prob fine to just tell everyone
      // that they're affected
      return true; 
    }
    return this.original.affectsConfiguration(`fuchsia.features.${name}`);
  }
}
const onDidChangeFeatureFlagEmitter: vscode.EventEmitter<FeatureFlagChangeEvent> 
  = new vscode.EventEmitter();

/**
 * Event emitted when a feature flag changes value.
 *
 * If you need to activate or deactivate features based on flags, listen to this.
 */
export const onDidChangeFeatureFlag: vscode.Event<FeatureFlagChangeEvent> 
  = onDidChangeFeatureFlagEmitter.event;

/**
 * activates the feature flag system, assuming the given extension version.
 *
 * You can get the extension version with `ctx.extension.packageJSON.version`.
 */
export function activate(extensionVersion: string) {
  const [_major, minor, _patch] = extensionVersion.split('.');
  const isPrerelease = parseInt(minor) % 2 === 1; // prerelease versions are always odd

  defaultStability = isPrerelease ? 'nightly' : 'stable';

  setStabilityFromConfig();
  watcher = vscode.workspace.onDidChangeConfiguration((evt) => {
    if (evt.affectsConfiguration('fuchsia.featurePreview')) {
      setStabilityFromConfig();
      onDidChangeFeatureFlagEmitter.fire(new FeatureFlagChangeEvent(evt, true));
      return;
    }

    if (evt.affectsConfiguration('fuchsia.features')) {
      onDidChangeFeatureFlagEmitter.fire(new FeatureFlagChangeEvent(evt));
    }
  });
}

/**
 * deactives the feature flag system
 */
export function deactivate() {
  if (watcher) {
    watcher.dispose();
  }
}

/** 
 * resets #stabilityLevel from either the #defaultStability or the override configuration
 * (fuchsia.featurePreview)
 */
function setStabilityFromConfig() {
  const override = vscode.workspace.getConfiguration('fuchsia').get('featurePreview');
  if (override === 'auto') {
    stabilityLevel = defaultStability;
  } else {
    stabilityLevel = override as flags.Stability;
  }
}

/** checks if lhs >= rhs, in stability terms */
function isAtLeast(lhs: flags.Stability, rhs: flags.Stability): boolean {
  const levels = {
    'never': -1,
    'nightly': 0,
    'stable': 1,
  };
  return levels[lhs] >= levels[rhs];
}

/**
 * Check if the given flag with with the given stability level would be enabled
 * in the current environment, either by configuration override or current
 * global stability level.
 *
 * You should pass in a string, like `flags.enabled('myFlag')`, and typescript's
 * typechecking will ensure it's a defined flag.
 */
export function enabled(flagName: flags.Known): boolean {
  const opt = vscode.workspace.getConfiguration('fuchsia.features').get(flagName);
  switch (opt) {
    case 'auto':
      const stability = flags.features[flagName].stability;
      return isAtLeast(stability, stabilityLevel);
    case 'enabled':
      return true;
    case 'disabled':
      return false;
    default:
      throw new Error(
        `feature flag ${flagName} set to invalid value "${opt}" (must be enabled|disabled|auto)`);
  }
}

// NB(sollyross): these are in a separate file so that we can load it in
// our build generator and inject the corresponding JSON into package.json

/**
 * The list of all feature flags.
 */
export { Stability, features } from './all-feature-flags';
