// 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';
const offlineFlag = 'offline';

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;
  final bool? _offline;

  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,
    bool? offline,
  }) : _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,
       _offline = offline {
    _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,
    offline: other._offline ?? _offline,
  );

  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;

  bool get offline => _offline ?? 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;

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

    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,
      offline: offline,
    );
  }
}

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

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