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

/// @docImport 'flutter_features.dart';
library;

import 'package:meta/meta.dart';

import 'base/context.dart';

/// The current [FeatureFlags] implementation.
FeatureFlags get featureFlags => context.get<FeatureFlags>()!;

/// The interface used to determine if a particular [Feature] is enabled.
///
/// This class is extended in google3. Whenever a new flag is added,
/// google3 must also be updated using a g3fix.
///
/// See also:
///
/// * [FlutterFeatureFlags], Flutter's implementation of this class.
/// * https://github.com/flutter/flutter/blob/main/docs/contributing/Feature-flags.md,
///   docs on feature flags and how to add or use them.
abstract class FeatureFlags {
  /// const constructor so that subclasses can be const.
  const FeatureFlags();

  /// Whether flutter desktop for linux is enabled.
  bool get isLinuxEnabled;

  /// Whether flutter desktop for macOS is enabled.
  bool get isMacOSEnabled;

  /// Whether flutter web is enabled.
  bool get isWebEnabled;

  /// Whether flutter desktop for Windows is enabled.
  bool get isWindowsEnabled;

  /// Whether android is enabled.
  bool get isAndroidEnabled;

  /// Whether iOS is enabled.
  bool get isIOSEnabled;

  /// Whether fuchsia is enabled.
  bool get isFuchsiaEnabled;

  /// Whether custom devices are enabled.
  bool get areCustomDevicesEnabled;

  /// Whether animations are used in the command line interface.
  bool get isCliAnimationEnabled;

  /// Whether native assets compilation and bundling is enabled.
  bool get isNativeAssetsEnabled;

  /// Whether dart data assets building and bundling is enabled.
  bool get isDartDataAssetsEnabled => false;

  /// Whether Swift Package Manager dependency management is enabled.
  bool get isSwiftPackageManagerEnabled;

  /// Whether to stop writing the `{FLUTTER_ROOT}/version` file.
  ///
  /// Tracking removal: <https://github.com/flutter/flutter/issues/171900>.
  bool get isOmitLegacyVersionFileEnabled;

  /// Whether desktop windowing is enabled.
  bool get isWindowingEnabled;

  /// Whether physical iOS devices are debugging with LLDB.
  bool get isLLDBDebuggingEnabled;

  /// Whether UIScene migration is enabled.
  bool get isUISceneMigrationEnabled;

  /// Whether a particular feature is enabled for the current channel.
  ///
  /// Prefer using one of the specific getters above instead of this API.
  bool isEnabled(Feature feature);

  /// All current Flutter feature flags.
  List<Feature> get allFeatures => const <Feature>[
    flutterWebFeature,
    flutterLinuxDesktopFeature,
    flutterMacOSDesktopFeature,
    flutterWindowsDesktopFeature,
    flutterAndroidFeature,
    flutterIOSFeature,
    flutterFuchsiaFeature,
    flutterCustomDevicesFeature,
    cliAnimation,
    nativeAssets,
    dartDataAssets,
    swiftPackageManager,
    omitLegacyVersionFile,
    windowingFeature,
    lldbDebugging,
    uiSceneMigration,
  ];

  /// All current Flutter feature flags that can be configured.
  ///
  /// [Feature.configSetting] is not `null`.
  Iterable<Feature> get allConfigurableFeatures {
    return allFeatures.where((Feature feature) => feature.configSetting != null);
  }

  /// All Flutter feature flags that are enabled.
  // This member is overriden in google3.
  Iterable<Feature> get allEnabledFeatures {
    return allFeatures.where(isEnabled);
  }
}

/// All current Flutter feature flags that can be configured.
///
/// [Feature.configSetting] is not `null`.
Iterable<Feature> get allConfigurableFeatures => featureFlags.allConfigurableFeatures;

/// The [Feature] for flutter web.
const flutterWebFeature = Feature.fullyEnabled(
  name: 'Flutter for web',
  configSetting: 'enable-web',
  environmentOverride: 'FLUTTER_WEB',
);

/// The [Feature] for macOS desktop.
const flutterMacOSDesktopFeature = Feature.fullyEnabled(
  name: 'support for desktop on macOS',
  configSetting: 'enable-macos-desktop',
  environmentOverride: 'FLUTTER_MACOS',
);

/// The [Feature] for Linux desktop.
const flutterLinuxDesktopFeature = Feature.fullyEnabled(
  name: 'support for desktop on Linux',
  configSetting: 'enable-linux-desktop',
  environmentOverride: 'FLUTTER_LINUX',
);

/// The [Feature] for Windows desktop.
const flutterWindowsDesktopFeature = Feature.fullyEnabled(
  name: 'support for desktop on Windows',
  configSetting: 'enable-windows-desktop',
  environmentOverride: 'FLUTTER_WINDOWS',
);

/// The [Feature] for Android devices.
const flutterAndroidFeature = Feature.fullyEnabled(
  name: 'Flutter for Android',
  configSetting: 'enable-android',
);

/// The [Feature] for iOS devices.
const flutterIOSFeature = Feature.fullyEnabled(
  name: 'Flutter for iOS',
  configSetting: 'enable-ios',
);

/// The [Feature] for Fuchsia support.
const flutterFuchsiaFeature = Feature(
  name: 'Flutter for Fuchsia',
  configSetting: 'enable-fuchsia',
  environmentOverride: 'FLUTTER_FUCHSIA',
  master: FeatureChannelSetting(available: true),
);

const flutterCustomDevicesFeature = Feature(
  name: 'early support for custom device types',
  configSetting: 'enable-custom-devices',
  environmentOverride: 'FLUTTER_CUSTOM_DEVICES',
  master: FeatureChannelSetting(available: true),
  beta: FeatureChannelSetting(available: true),
  stable: FeatureChannelSetting(available: true),
);

/// The [Feature] for CLI animations.
///
/// The TERM environment variable set to "dumb" turns this off.
const cliAnimation = Feature.fullyEnabled(
  name: 'animations in the command line interface',
  configSetting: 'cli-animations',
);

/// Enable native assets compilation and bundling.
const nativeAssets = Feature(
  name: 'native assets compilation and bundling',
  configSetting: 'enable-native-assets',
  environmentOverride: 'FLUTTER_NATIVE_ASSETS',
  master: FeatureChannelSetting(available: true, enabledByDefault: true),
  beta: FeatureChannelSetting(available: true, enabledByDefault: true),
  stable: FeatureChannelSetting(available: true, enabledByDefault: true),
);

/// Enable Dart data assets building and bundling.
const dartDataAssets = Feature(
  name: 'Dart data assets building and bundling',
  configSetting: 'enable-dart-data-assets',
  environmentOverride: 'FLUTTER_DART_DATA_ASSETS',
  master: FeatureChannelSetting(available: true),
);

/// Enable Swift Package Manager as a darwin dependency manager.
const swiftPackageManager = Feature(
  name: 'support for Swift Package Manager for iOS and macOS',
  configSetting: 'enable-swift-package-manager',
  environmentOverride: 'FLUTTER_SWIFT_PACKAGE_MANAGER',
  master: FeatureChannelSetting(available: true),
  beta: FeatureChannelSetting(available: true),
  stable: FeatureChannelSetting(available: true),
);

/// Whether to continue writing the `{FLUTTER_ROOT}/version` legacy file.
///
/// Tracking removal: <https://github.com/flutter/flutter/issues/171900>.
const omitLegacyVersionFile = Feature.fullyEnabled(
  name: 'stops writing the legacy version file',
  configSetting: 'omit-legacy-version-file',
  extraHelpText:
      'If set, the file {FLUTTER_ROOT}/version is no longer written as part of '
      'the flutter tool execution; a newer file format has existed for some '
      'time in {FLUTTER_ROOT}/bin/cache/flutter.version.json.',
);

/// Whether desktop windowing is enabled.
///
/// See: https://github.com/flutter/flutter/issues/30701.
const windowingFeature = Feature(
  name: 'support for windowing on macOS, Linux, and Windows',
  configSetting: 'enable-windowing',
  environmentOverride: 'FLUTTER_WINDOWING',
  runtimeId: 'windowing',
  master: FeatureChannelSetting(available: true),
);

/// Enable LLDB debugging for physical iOS devices. When LLDB debugging is off,
/// Xcode debugging is used instead.
///
/// Requires iOS 17+ and Xcode 26+. If those requirements are not met, the previous
/// default debugging method is used instead.
const lldbDebugging = Feature(
  name: 'support for debugging with LLDB for physical iOS devices',
  extraHelpText:
      'If LLDB debugging is off, Xcode debugging is used instead. '
      'Only available for iOS 17 or newer devices. Requires Xcode 26 or greater.',
  configSetting: 'enable-lldb-debugging',
  environmentOverride: 'FLUTTER_LLDB_DEBUGGING',
  master: FeatureChannelSetting(available: true, enabledByDefault: true),
  beta: FeatureChannelSetting(available: true, enabledByDefault: true),
  stable: FeatureChannelSetting(available: true, enabledByDefault: true),
);

/// Enable UIScene lifecycle migration for iOS apps. When enabled, if possible the tool will
/// attempt to auto-migrate the app. Otherwise, it will print a warning with instructions on how to
/// migrate manually.
const uiSceneMigration = Feature(
  name: 'support for migrating to UIScene lifecycle',
  extraHelpText:
      'If enabled, Flutter will migrate your app to iOS UIScene lifecycle if possible or '
      'otherwise instruct you to migrate manually.',
  configSetting: 'enable-uiscene-migration',
  environmentOverride: 'FLUTTER_UISCENE_MIGRATION',
  master: FeatureChannelSetting(available: true),
  beta: FeatureChannelSetting(available: true),
  stable: FeatureChannelSetting(available: true),
);

/// A [Feature] is a process for conditionally enabling tool features.
///
/// All settings are optional, and if not provided will generally default to
/// a "safe" value, such as being off.
///
/// The top level feature settings can be provided to apply to all channels.
/// Otherwise, more specific settings take precedence over higher level
/// settings.
class Feature {
  /// Creates a [Feature].
  const Feature({
    required this.name,
    this.environmentOverride,
    this.configSetting,
    this.runtimeId,
    this.extraHelpText,
    this.master = const FeatureChannelSetting(),
    this.beta = const FeatureChannelSetting(),
    this.stable = const FeatureChannelSetting(),
  });

  /// Creates a [Feature] that is fully enabled across channels.
  const Feature.fullyEnabled({
    required this.name,
    this.environmentOverride,
    this.configSetting,
    this.runtimeId,
    this.extraHelpText,
  }) : master = const FeatureChannelSetting(available: true, enabledByDefault: true),
       beta = const FeatureChannelSetting(available: true, enabledByDefault: true),
       stable = const FeatureChannelSetting(available: true, enabledByDefault: true);

  /// The user visible name for this feature.
  final String name;

  /// The settings for the master branch and other unknown channels.
  final FeatureChannelSetting master;

  /// The settings for the beta branch.
  final FeatureChannelSetting beta;

  /// The settings for the stable branch.
  final FeatureChannelSetting stable;

  /// The name of an environment variable that can override the setting.
  ///
  /// The environment variable needs to be set to the value 'true'. This is
  /// only intended for usage by CI and not as an advertised method to enable
  /// a feature.
  ///
  /// If not provided, defaults to `null` meaning there is no override.
  final String? environmentOverride;

  /// The name of a setting that can be used to enable this feature.
  ///
  /// If not provided, defaults to `null` meaning there is no config setting.
  final String? configSetting;

  /// The unique identifier for this feature at runtime.
  ///
  /// If not `null`, the Flutter framework's enabled feature flags will
  /// contain this value if this feature is enabled.
  final String? runtimeId;

  /// Additional text to add to the end of the help message.
  ///
  /// If not provided, defaults to `null` meaning there is no additional text.
  final String? extraHelpText;

  /// A help message for the `flutter config` command, or null if unsupported.
  String? generateHelpMessage() {
    if (configSetting == null) {
      return null;
    }
    final buffer = StringBuffer('Enable or disable $name.');
    final channels = <String>[
      if (master.available) 'master',
      if (beta.available) 'beta',
      if (stable.available) 'stable',
    ];
    // Add channel info for settings only on some channels.
    if (channels.length == 1) {
      buffer.write('\nThis setting applies only to the ${channels.single} channel.');
    } else if (channels.length == 2) {
      buffer.write('\nThis setting applies only to the ${channels.join(' and ')} channels.');
    }
    if (extraHelpText != null) {
      buffer.write(' $extraHelpText');
    }
    return buffer.toString();
  }

  /// Retrieve the correct setting for the provided `channel`.
  FeatureChannelSetting getSettingForChannel(String channel) {
    return switch (channel) {
      'stable' => stable,
      'beta' => beta,
      'master' || _ => master,
    };
  }
}

/// A description of the conditions to enable a feature for a particular channel.
@immutable
final class FeatureChannelSetting {
  const FeatureChannelSetting({this.available = false, this.enabledByDefault = false});

  /// Whether the feature is available on this channel.
  ///
  /// If not provided, defaults to `false`. This implies that the feature
  /// cannot be enabled even by the settings below.
  final bool available;

  /// Whether the feature is enabled by default.
  ///
  /// If not provided, defaults to `false`.
  final bool enabledByDefault;

  @override
  bool operator ==(Object other) {
    return other is FeatureChannelSetting &&
        available == other.available &&
        enabledByDefault == other.enabledByDefault;
  }

  @override
  int get hashCode => Object.hash(available, enabledByDefault);

  @override
  String toString() {
    return 'FeatureChannelSetting <available: $available, enabledByDefault: $enabledByDefault>';
  }
}
