// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:args/args.dart';
import 'package:dwds/dwds.dart';
import 'package:logging/logging.dart';

import '../logging.dart';
import 'shared.dart';

const autoOption = 'auto';
const chromeDebugPortFlag = 'chrome-debug-port';
const debugExtensionFlag = 'debug-extension';
const debugFlag = 'debug';
const enableInjectedClientFlag = 'injected-client';
const hostnameFlag = 'hostname';
const tlsCertChainFlag = 'tls-cert-chain';
const tlsCertKeyFlag = 'tls-cert-key';
const hotReloadFlag = 'hot-reload';
const hotRestartFlag = 'hot-restart';
const launchAppOption = 'launch-app';
const launchInChromeFlag = 'launch-in-chrome';
const userDataDirFlag = 'user-data-dir';
const liveReloadFlag = 'live-reload';
const logRequestsFlag = 'log-requests';
const outputFlag = 'output';
const outputNone = 'NONE';
const releaseFlag = 'release';
const requireBuildWebCompilersFlag = 'build-web-compilers';
const enableExpressionEvaluationFlag = 'enable-expression-evaluation';
const verboseFlag = 'verbose';
const nullSafetyFlag = 'null-safety';
const nullSafetySound = 'sound';
const nullSafetyUnsound = 'unsound';
const nullSafetyAuto = 'auto';
const disableDdsFlag = 'disable-dds';
const enableExperimentOption = 'enable-experiment';
const canaryFeaturesFlag = 'canary';

ReloadConfiguration _parseReloadConfiguration(ArgResults argResults) {
  var auto = argResults.options.contains(autoOption)
      ? argResults[autoOption] as String?
      : null;

  void handleDeprecatedFlag(String flag, String autoFallback) {
    if (argResults.options.contains(flag) &&
        argResults.wasParsed(flag) &&
        (argResults[flag] as bool? ?? false)) {
      logWriter(
          Level.WARNING,
          '--$flag is deprecated please use --auto=$autoFallback instead '
          '(this has been automatically selected).');
      if (auto != null) {
        logWriter(
            Level.WARNING,
            'Only one --auto option is allowed, got $flag which corresponds '
            'to --auto=$autoFallback, but already got --auto=$auto');
      } else {
        auto = autoFallback;
      }
    }
  }

  handleDeprecatedFlag(hotReloadFlag, 'reload');
  handleDeprecatedFlag(hotRestartFlag, 'restart');
  handleDeprecatedFlag(liveReloadFlag, 'refresh');

  switch (auto) {
    case 'reload':
      logWriter(
          Level.WARNING,
          'Hot reload is not yet supported for web projects. '
          'Please try --auto=restart instead.');
      return ReloadConfiguration.none;
    case 'restart':
      return ReloadConfiguration.hotRestart;
    case 'refresh':
      return ReloadConfiguration.liveReload;
    default:
      return ReloadConfiguration.none;
  }
}

class Configuration {
  final bool? _autoRun;
  final int? _chromeDebugPort;
  final bool? _debugExtension;
  final bool? _debug;
  final bool? _enableInjectedClient;
  final String? _hostname;
  final String? _tlsCertChain;
  final String? _tlsCertKey;
  final List<String>? _launchApps;
  final bool? _launchInChrome;
  final String? _userDataDir;
  final bool? _logRequests;
  final String? _output;
  final String? outputInput;
  final String? outputPath;
  final bool? _release;
  final ReloadConfiguration? _reload;
  final bool? _requireBuildWebCompilers;
  final bool? _enableExpressionEvaluation;
  final bool? _verbose;
  final bool? _disableDds;
  final String? _nullSafety;
  final List<String>? _experiments;
  final bool? _canaryFeatures;

  Configuration({
    bool? autoRun,
    int? chromeDebugPort,
    bool? debugExtension,
    bool? debug,
    bool? enableInjectedClient,
    String? hostname,
    String? tlsCertChain,
    String? tlsCertKey,
    List<String>? launchApps,
    bool? launchInChrome,
    String? userDataDir,
    bool? logRequests,
    String? output,
    this.outputInput,
    this.outputPath,
    ReloadConfiguration? reload,
    bool? release,
    bool? requireBuildWebCompilers,
    bool? enableExpressionEvaluation,
    bool? verbose,
    bool? disableDds,
    String? nullSafety,
    List<String>? experiments,
    bool? canaryFeatures,
  })  : _autoRun = autoRun,
        _chromeDebugPort = chromeDebugPort,
        _debugExtension = debugExtension,
        _debug = debug,
        _enableInjectedClient = enableInjectedClient,
        _hostname = hostname,
        _tlsCertChain = tlsCertChain,
        _tlsCertKey = tlsCertKey,
        _launchApps = launchApps,
        _launchInChrome = launchInChrome,
        _userDataDir = userDataDir,
        _logRequests = logRequests,
        _output = output,
        _release = release,
        _reload = reload,
        _requireBuildWebCompilers = requireBuildWebCompilers,
        _disableDds = disableDds,
        _enableExpressionEvaluation = enableExpressionEvaluation,
        _verbose = verbose,
        _nullSafety = nullSafety,
        _experiments = experiments,
        _canaryFeatures = canaryFeatures {
    _validateConfiguration();
  }

  void _validateConfiguration() {
    // Both null and an empty string are valid values for outputInput. For any
    // other value, we need to ensure it's a top-level dir.
    if (outputInput?.isNotEmpty ?? false) ensureIsTopLevelDir(outputInput!);

    if ((tlsCertKey != null && tlsCertChain == null) ||
        (tlsCertKey == null && tlsCertChain != null)) {
      throw InvalidConfiguration(
          'Must use --$tlsCertKey with --$tlsCertChain.');
    }
    if (debug && chromeDebugPort == 0 && !launchInChrome) {
      throw InvalidConfiguration(
          'Must either use --$chromeDebugPortFlag or --$launchInChromeFlag '
          'with --$debugFlag.');
    }

    // Check that no debugging options were passed if the injected client is
    // disabled.
    if (!enableInjectedClient) {
      if (debug) {
        throw InvalidConfiguration(
            '--$debugFlag cannot be used with --no-$enableInjectedClientFlag');
      }
      if (debugExtension) {
        throw InvalidConfiguration('--$debugExtensionFlag cannot be used with '
            '--no-$enableInjectedClientFlag');
      }
      if (chromeDebugPort != 0) {
        throw InvalidConfiguration('--$chromeDebugPortFlag cannot be used '
            'with --no-$enableInjectedClientFlag');
      }
    }

    if (launchApps.isNotEmpty && !launchInChrome) {
      throw InvalidConfiguration(
          '--$launchAppOption can only be used with --$launchInChromeFlag');
    }

    if (userDataDir != null && !launchInChrome) {
      throw InvalidConfiguration(
          '--$userDataDir can only be used with --$launchInChromeFlag');
    }
  }

  /// Creates a new [Configuration] with all non-null fields from
  /// [other] overriding the values of `this`.
  Configuration _override(Configuration other) => Configuration(
      autoRun: other._autoRun ?? _autoRun,
      chromeDebugPort: other._chromeDebugPort ?? _chromeDebugPort,
      debugExtension: other._debugExtension ?? _debugExtension,
      debug: other._debug ?? _debug,
      enableInjectedClient:
          other._enableInjectedClient ?? _enableInjectedClient,
      hostname: other._hostname ?? _hostname,
      tlsCertChain: other._tlsCertChain ?? _tlsCertChain,
      tlsCertKey: other._tlsCertKey ?? _tlsCertKey,
      launchApps: other._launchApps ?? _launchApps,
      launchInChrome: other._launchInChrome ?? _launchInChrome,
      userDataDir: other._userDataDir ?? _userDataDir,
      logRequests: other._logRequests ?? _logRequests,
      output: other._output ?? _output,
      release: other._release ?? _release,
      reload: other._reload ?? _reload,
      requireBuildWebCompilers:
          other._requireBuildWebCompilers ?? _requireBuildWebCompilers,
      disableDds: other._disableDds ?? _disableDds,
      enableExpressionEvaluation:
          other._enableExpressionEvaluation ?? _enableExpressionEvaluation,
      verbose: other._verbose ?? _verbose,
      nullSafety: other._nullSafety ?? _nullSafety,
      experiments: other._experiments ?? _experiments,
      canaryFeatures: other._canaryFeatures ?? _canaryFeatures);

  factory Configuration.noInjectedClientDefaults() =>
      Configuration(autoRun: false, debug: false, debugExtension: false);

  // Whether the application should automatically run when loaded.
  bool get autoRun => _autoRun ?? true;

  int get chromeDebugPort => _chromeDebugPort ?? 0;

  bool get debugExtension => _debugExtension ?? false;

  bool get debug => _debug ?? false;

  bool get disableDds => _disableDds ?? false;

  bool get enableInjectedClient => _enableInjectedClient ?? true;

  String get hostname => _hostname ?? 'localhost';

  String? get tlsCertChain => _tlsCertChain;

  String? get tlsCertKey => _tlsCertKey;

  List<String> get launchApps => _launchApps ?? [];

  bool get launchInChrome => _launchInChrome ?? false;

  String? get userDataDir => _userDataDir;

  bool get logRequests => _logRequests ?? false;

  String get output => _output ?? outputNone;

  bool get release => _release ?? false;

  ReloadConfiguration get reload => _reload ?? ReloadConfiguration.none;

  bool get requireBuildWebCompilers => _requireBuildWebCompilers ?? true;

  bool get enableExpressionEvaluation => _enableExpressionEvaluation ?? true;

  bool get verbose => _verbose ?? false;

  /// Null safety mode:
  ///
  /// 'sound', 'unsound', or 'auto'.
  /// 'auto' indicates that the default `package:build_web_compilers`
  /// behavior should be used.
  String get nullSafety => _nullSafety ?? 'auto';

  List<String> get experiments => _experiments ?? [];

  bool get canaryFeatures => _canaryFeatures ?? false;

  /// Returns a new configuration with values updated from the parsed args.
  static Configuration fromArgs(ArgResults? argResults,
      {Configuration? defaultConfiguration}) {
    defaultConfiguration ??= Configuration();
    if (argResults == null) return defaultConfiguration;

    final enableInjectedClient =
        argResults.options.contains(enableInjectedClientFlag)
            ? (argResults[enableInjectedClientFlag] as bool)
            : defaultConfiguration.enableInjectedClient;

    // Change the defaults when we have no injected client to disable all
    // debugging features.
    //
    // After parsing we check these defaults weren't overridden as well.
    if (!enableInjectedClient) {
      defaultConfiguration = defaultConfiguration
          ._override(Configuration.noInjectedClientDefaults());
    }

    final chromeDebugPort = argResults.options.contains(chromeDebugPortFlag)
        ? int.parse(argResults[chromeDebugPortFlag] as String)
        : defaultConfiguration.chromeDebugPort;

    final debugExtension = argResults.options.contains(debugExtensionFlag)
        ? argResults[debugExtensionFlag] as bool?
        : defaultConfiguration.debugExtension;

    final debug = argResults.options.contains(debugFlag)
        ? argResults[debugFlag] as bool?
        : defaultConfiguration.debug;

    final hostname = argResults.options.contains(hostnameFlag)
        ? argResults[hostnameFlag] as String?
        : defaultConfiguration.hostname;

    final tlsCertChain = argResults.options.contains(tlsCertChainFlag)
        ? argResults[tlsCertChainFlag] as String?
        : defaultConfiguration.tlsCertChain;

    final tlsCertKey = argResults.options.contains(tlsCertKeyFlag)
        ? argResults[tlsCertKeyFlag] as String?
        : defaultConfiguration.tlsCertKey;

    final launchApps = argResults.options.contains(launchAppOption) &&
            argResults.wasParsed(launchAppOption)
        ? argResults[launchAppOption] as List<String>?
        : defaultConfiguration.launchApps;

    final launchInChrome = argResults.options.contains(launchInChromeFlag) &&
            argResults.wasParsed(launchInChromeFlag)
        ? argResults[launchInChromeFlag] as bool?
        // We want to default to launch chrome if the user provides just --debug
        // and not --chrome-debug-port.
        : debug! &&
                !(argResults.options.contains(launchInChromeFlag) &&
                    argResults.wasParsed(chromeDebugPortFlag))
            ? true
            : defaultConfiguration.launchInChrome;

    final userDataDir = argResults.options.contains(userDataDirFlag)
        ? argResults[userDataDirFlag] as String?
        : defaultConfiguration.userDataDir;

    final logRequests = argResults.options.contains(logRequestsFlag)
        ? argResults[logRequestsFlag] as bool?
        : defaultConfiguration.logRequests;

    final output = argResults.options.contains(outputFlag)
        ? argResults[outputFlag] as String?
        : defaultConfiguration.output;

    String? outputPath;
    String outputInput;
    if (output == 'NONE' || output == null) {
      // The empty string means build everything.
      outputInput = '';
    } else {
      final splitOutput = output.split(':');
      if (splitOutput.length == 1) {
        // The empty string means build everything.
        outputInput = '';
        outputPath = output;
      } else {
        outputInput = splitOutput.first;
        outputPath = splitOutput.skip(1).join(':');
      }
    }

    final release = argResults.options.contains(releaseFlag)
        ? argResults[releaseFlag] as bool?
        : defaultConfiguration.release;

    final requireBuildWebCompilers =
        argResults.options.contains(requireBuildWebCompilersFlag)
            ? argResults[requireBuildWebCompilersFlag] as bool?
            : defaultConfiguration.requireBuildWebCompilers;

    final enableExpressionEvaluation =
        argResults.options.contains(enableExpressionEvaluationFlag)
            ? argResults[enableExpressionEvaluationFlag] as bool?
            : defaultConfiguration.enableExpressionEvaluation;

    final verbose = argResults.options.contains(verboseFlag)
        ? argResults[verboseFlag] as bool?
        : defaultConfiguration.verbose;

    final nullSafety = argResults.options.contains(nullSafetyFlag)
        ? argResults[nullSafetyFlag] as String?
        : defaultConfiguration.nullSafety;

    final disableDds = argResults.options.contains(disableDdsFlag)
        ? argResults[disableDdsFlag] as bool?
        : defaultConfiguration.disableDds;

    final experiments = argResults.options.contains(enableExperimentOption) &&
            argResults.wasParsed(enableExperimentOption)
        ? argResults[enableExperimentOption] as List<String>?
        : defaultConfiguration.experiments;

    final canaryFeatures = argResults.options.contains(canaryFeaturesFlag)
        ? argResults[canaryFeaturesFlag] as bool?
        : defaultConfiguration.canaryFeatures;

    return Configuration(
      autoRun: defaultConfiguration.autoRun,
      chromeDebugPort: chromeDebugPort,
      debugExtension: debugExtension,
      debug: debug,
      enableInjectedClient: enableInjectedClient,
      hostname: hostname,
      tlsCertChain: tlsCertChain,
      tlsCertKey: tlsCertKey,
      launchApps: launchApps,
      launchInChrome: launchInChrome,
      userDataDir: userDataDir,
      logRequests: logRequests,
      output: output,
      outputInput: outputInput,
      outputPath: outputPath,
      release: release,
      reload: _parseReloadConfiguration(argResults),
      requireBuildWebCompilers: requireBuildWebCompilers,
      disableDds: disableDds,
      enableExpressionEvaluation: enableExpressionEvaluation,
      verbose: verbose,
      nullSafety: nullSafety,
      experiments: experiments,
      canaryFeatures: canaryFeatures,
    );
  }
}

class InvalidConfiguration implements Exception {
  final String details;
  InvalidConfiguration(this.details);

  @override
  String toString() {
    return 'Invalid configuration: $details';
  }
}
