// Copyright (c) 2015, 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 'dart:io' as io;

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/sdk.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/driver.dart';
import 'package:args/args.dart';
import 'package:pub_semver/pub_semver.dart';

const _analysisOptionsFileOption = 'options';
const _binaryName = 'dartanalyzer';
const _defaultLanguageVersionOption = 'default-language-version';
const _defineVariableOption = 'D';
const _enableExperimentOption = 'enable-experiment';
const _enableInitializingFormalAccessFlag = 'initializing-formal-access';
const _ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags';
const _implicitCastsFlag = 'implicit-casts';
const _lintsFlag = 'lints';
const _noImplicitDynamicFlag = 'no-implicit-dynamic';
const _packagesOption = 'packages';
const _sdkPathOption = 'dart-sdk';

/// Shared exit handler.
///
/// *Visible for testing.*
ExitHandler exitHandler = io.exit;

T cast<T>(dynamic value) => value as T;

T? castNullable<T>(dynamic value) => value as T?;

/// Print the given [message] to stderr and exit with the given [exitCode].
void printAndFail(String message, {int exitCode = 15}) {
  errorSink.writeln(message);
  exitHandler(exitCode);
}

/// Exit handler.
///
/// *Visible for testing.*
typedef ExitHandler = void Function(int code);

/// Analyzer commandline configuration options.
class CommandLineOptions {
  final ArgResults _argResults;

  /// The file path of the analysis options file that should be used in place of
  /// any file in the root directory or a parent of the root directory,
  /// or `null` if the normal lookup mechanism should be used.
  String? defaultAnalysisOptionsPath;

  /// The file path of the .packages file that should be used in place of any
  /// file found using the normal (Package Specification DEP) lookup mechanism,
  /// or `null` if the normal lookup mechanism should be used.
  String? defaultPackagesPath;

  /// A table mapping variable names to values for the declared variables.
  final Map<String, String> declaredVariables = {};

  /// The path to the dart SDK.
  String? dartSdkPath;

  /// Whether to disable cache flushing. This option can improve analysis
  /// speed at the expense of memory usage. It may also be useful for working
  /// around bugs.
  final bool disableCacheFlushing;

  /// Whether to report hints
  final bool disableHints;

  /// Whether to display version information
  final bool displayVersion;

  /// Whether to ignore unrecognized flags
  final bool ignoreUnrecognizedFlags;

  /// Whether to log additional analysis messages and exceptions
  final bool log;

  /// Whether to use 'json' format for error display
  final bool jsonFormat;

  /// Whether to use 'machine' format for error display
  final bool machineFormat;

  /// The path to a file to write a performance log.
  /// (Or null if not enabled.)
  final String? perfReport;

  /// Batch mode (for unit testing)
  final bool batchMode;

  /// Whether to show package: warnings
  final bool showPackageWarnings;

  /// If not null, show package: warnings only for matching packages.
  final String? showPackageWarningsPrefix;

  /// Whether to show SDK warnings
  final bool showSdkWarnings;

  /// The source files to analyze
  final List<String> sourceFiles;

  /// Whether to treat warnings as fatal
  final bool warningsAreFatal;

  /// Whether to treat info level items as fatal
  final bool infosAreFatal;

  /// Whether to treat lints as fatal
  // TODO(devoncarew): Deprecate and remove this flag.
  final bool lintsAreFatal;

  /// Emit output in a verbose mode.
  final bool verbose;

  /// Use ANSI color codes for output.
  final bool color;

  /// Whether we should analyze the given source for the purposes of training a
  /// Dart analyzer snapshot.
  final bool trainSnapshot;

  /// Initialize options from the given parsed [args].
  CommandLineOptions._fromArgs(
    ResourceProvider resourceProvider,
    ArgResults args,
  )   : _argResults = args,
        dartSdkPath = castNullable(args[_sdkPathOption]),
        disableCacheFlushing = cast(args['disable-cache-flushing']),
        disableHints = cast(args['no-hints']),
        displayVersion = cast(args['version']),
        ignoreUnrecognizedFlags = cast(args[_ignoreUnrecognizedFlagsFlag]),
        log = cast(args['log']),
        jsonFormat = args['format'] == 'json',
        machineFormat = args['format'] == 'machine',
        perfReport = castNullable(args['x-perf-report']),
        batchMode = cast(args['batch']),
        showPackageWarnings = cast(args['show-package-warnings']) ||
            cast(args['package-warnings']) ||
            args['x-package-warnings-prefix'] != null,
        showPackageWarningsPrefix =
            castNullable(args['x-package-warnings-prefix']),
        showSdkWarnings = cast(args['sdk-warnings']),
        sourceFiles = args.rest,
        infosAreFatal = cast(args['fatal-infos']) || cast(args['fatal-hints']),
        warningsAreFatal = cast(args['fatal-warnings']),
        lintsAreFatal = cast(args['fatal-lints']),
        trainSnapshot = cast(args['train-snapshot']),
        verbose = cast(args['verbose']),
        color = cast(args['color']) {
    //
    // File locations.
    //
    defaultAnalysisOptionsPath = _absoluteNormalizedPath(
      resourceProvider,
      castNullable(args[_analysisOptionsFileOption]),
    );
    defaultPackagesPath = _absoluteNormalizedPath(
      resourceProvider,
      castNullable(args[_packagesOption]),
    );

    //
    // Declared variables.
    //
    var variables = (args[_defineVariableOption] as List).cast<String>();
    for (var variable in variables) {
      var index = variable.indexOf('=');
      if (index < 0) {
        // TODO (brianwilkerson) Decide the semantics we want in this case.
        // The VM prints "No value given to -D option", then tries to load '-Dfoo'
        // as a file and dies. Unless there was nothing after the '-D', in which
        // case it prints the warning and ignores the option.
      } else {
        var name = variable.substring(0, index);
        if (name.isNotEmpty) {
          // TODO (brianwilkerson) Decide the semantics we want in the case where
          // there is no name. If there is no name, the VM tries to load a file
          // named '-D' and dies.
          declaredVariables[name] = variable.substring(index + 1);
        }
      }
    }
  }

  /// The default language version for files that are not in a package.
  /// (Or null if no default language version to force.)
  String? get defaultLanguageVersion {
    return castNullable(_argResults[_defaultLanguageVersionOption]);
  }

  /// A list of the names of the experiments that are to be enabled.
  List<String>? get enabledExperiments {
    return castNullable(_argResults[_enableExperimentOption]);
  }

  bool? get implicitCasts => _argResults[_implicitCastsFlag] as bool?;

  bool? get lints => _argResults[_lintsFlag] as bool?;

  bool? get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool?;

  /// Update the [analysisOptions] with flags that the user specified
  /// explicitly. The [analysisOptions] are usually loaded from one of
  /// `analysis_options.yaml` files, possibly with includes. We consider
  /// flags that the user specified as command line options more important,
  /// so override the corresponding options.
  void updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
    var defaultLanguageVersion = this.defaultLanguageVersion;
    if (defaultLanguageVersion != null) {
      var nonPackageLanguageVersion =
          Version.parse('$defaultLanguageVersion.0');
      analysisOptions.nonPackageLanguageVersion = nonPackageLanguageVersion;
      analysisOptions.nonPackageFeatureSet = FeatureSet.latestLanguageVersion()
          .restrictToVersion(nonPackageLanguageVersion);
    }

    var enabledExperiments = this.enabledExperiments!;
    if (enabledExperiments.isNotEmpty) {
      analysisOptions.contextFeatures = FeatureSet.fromEnableFlags2(
        sdkLanguageVersion: ExperimentStatus.currentVersion,
        flags: enabledExperiments,
      );
    }

    var implicitCasts = this.implicitCasts;
    if (implicitCasts != null) {
      analysisOptions.implicitCasts = implicitCasts;
    }

    var lints = this.lints;
    if (lints != null) {
      analysisOptions.lint = lints;
    }

    var noImplicitDynamic = this.noImplicitDynamic;
    if (noImplicitDynamic != null) {
      analysisOptions.implicitDynamic = !noImplicitDynamic;
    }
  }

  /// Return a list of command-line arguments containing all of the given [args]
  /// that are defined by the given [parser]. An argument is considered to be
  /// defined by the parser if
  /// - it starts with '--' and the rest of the argument (minus any value
  ///   introduced by '=') is the name of a known option,
  /// - it starts with '-' and the rest of the argument (minus any value
  ///   introduced by '=') is the name of a known abbreviation, or
  /// - it starts with something other than '--' or '-'.
  ///
  /// This function allows command-line tools to implement the
  /// '--ignore-unrecognized-flags' option.
  static List<String> filterUnknownArguments(
      List<String> args, ArgParser parser) {
    var knownOptions = <String>{};
    var knownAbbreviations = <String>{};
    parser.options.forEach((String name, Option option) {
      knownOptions.add(name);
      var abbreviation = option.abbr;
      if (abbreviation != null) {
        knownAbbreviations.add(abbreviation);
      }
      if (option.negatable ?? false) {
        knownOptions.add('no-$name');
      }
    });
    String optionName(int prefixLength, String argument) {
      var equalsOffset = argument.lastIndexOf('=');
      if (equalsOffset < 0) {
        return argument.substring(prefixLength);
      }
      return argument.substring(prefixLength, equalsOffset);
    }

    var filtered = <String>[];
    for (var i = 0; i < args.length; i++) {
      var argument = args[i];
      if (argument.startsWith('--') && argument.length > 2) {
        if (knownOptions.contains(optionName(2, argument))) {
          filtered.add(argument);
        }
      } else if (argument.startsWith('-D') && argument.indexOf('=') > 0) {
        filtered.add(argument);
      }
      if (argument.startsWith('-') && argument.length > 1) {
        if (knownAbbreviations.contains(optionName(1, argument))) {
          filtered.add(argument);
        }
      } else {
        filtered.add(argument);
      }
    }
    return filtered;
  }

  /// Parse [args] into [CommandLineOptions] describing the specified
  /// analyzer options. In case of a format error, calls [printAndFail], which
  /// by default prints an error message to stderr and exits.
  static CommandLineOptions? parse(
      ResourceProvider resourceProvider, List<String> args,
      {void Function(String msg) printAndFail = printAndFail}) {
    var options = _parse(resourceProvider, args);

    /// Only happens in testing.
    if (options == null) {
      return null;
    }

    // Check SDK.
    {
      var sdkPath = options.dartSdkPath;

      // Check that SDK is existing directory.
      if (sdkPath != null) {
        if (!(io.Directory(sdkPath)).existsSync()) {
          printAndFail('Invalid Dart SDK path: $sdkPath');
          return null; // Only reachable in testing.
        }
      }

      // Infer if unspecified.
      sdkPath ??= getSdkPath(args);

      var pathContext = resourceProvider.pathContext;
      options.dartSdkPath = file_paths.absoluteNormalized(pathContext, sdkPath);
    }

    return options;
  }

  static String? _absoluteNormalizedPath(
    ResourceProvider resourceProvider,
    String? path,
  ) {
    if (path == null) {
      return null;
    }
    var pathContext = resourceProvider.pathContext;
    return pathContext.normalize(
      pathContext.absolute(path),
    );
  }

  /// Add the standard flags and options to the given [parser]. The standard flags
  /// are those that are typically used to control the way in which the code is
  /// analyzed.
  ///
  /// TODO(danrubel) Update DDC to support all the options defined in this method
  /// then remove the [ddc] named argument from this method.
  static void _defineAnalysisArguments(ArgParser parser,
      {bool hide = true, bool ddc = false}) {
    parser.addOption(_sdkPathOption,
        help: 'The path to the Dart SDK.', hide: ddc && hide);
    parser.addOption(_analysisOptionsFileOption,
        help: 'Path to an analysis options file.', hide: ddc && hide);
    parser.addFlag('strong',
        help: 'Enable strong mode (deprecated); this option is now ignored.',
        defaultsTo: true,
        hide: true,
        negatable: true);
    parser.addFlag('declaration-casts',
        negatable: true,
        help:
            'Disable declaration casts in strong mode (https://goo.gl/cTLz40)\n'
            'This option is now ignored and will be removed in a future release.',
        hide: ddc && hide);
    parser.addMultiOption(_enableExperimentOption,
        help: 'Enable one or more experimental features. If multiple features '
            'are being added, they should be comma separated.',
        splitCommas: true);
    parser.addFlag(_implicitCastsFlag,
        negatable: true,
        help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40).',
        defaultsTo: null,
        hide: ddc && hide);
    parser.addFlag(_noImplicitDynamicFlag,
        defaultsTo: null,
        negatable: false,
        help: 'Disable implicit dynamic (https://goo.gl/m0UgXD).',
        hide: ddc && hide);

    //
    // Hidden flags and options.
    //
    parser.addMultiOption(_defineVariableOption,
        abbr: 'D',
        help:
            'Define an environment declaration. For example, "-Dfoo=bar" defines '
            'an environment declaration named "foo" whose value is "bar".',
        hide: hide);
    parser.addOption(_packagesOption,
        help: 'The path to the package resolution configuration file, which '
            'supplies a mapping of package names\ninto paths.',
        hide: ddc);
    parser.addFlag(_enableInitializingFormalAccessFlag,
        help:
            'Enable support for allowing access to field formal parameters in a '
            'constructor\'s initializer list (deprecated).',
        defaultsTo: false,
        negatable: false,
        hide: hide || ddc);
    if (!ddc) {
      parser.addFlag(_lintsFlag,
          help: 'Show lint results.', defaultsTo: null, negatable: true);
    }
  }

  static String _getVersion() {
    try {
      // This is relative to bin/snapshot, so ../..
      var versionPath =
          io.Platform.script.resolve('../../version').toFilePath();
      var versionFile = io.File(versionPath);
      return versionFile.readAsStringSync().trim();
    } catch (_) {
      // This happens when the script is not running in the context of an SDK.
      return '<unknown>';
    }
  }

  static CommandLineOptions? _parse(
    ResourceProvider resourceProvider,
    List<String> args,
  ) {
    var verbose = args.contains('-v') || args.contains('--verbose');
    var hide = !verbose;

    var parser = ArgParser(allowTrailingOptions: true);

    if (!hide) {
      parser.addSeparator('General options:');
    }

    // TODO(devoncarew): This defines some hidden flags, which would be better
    // defined with the rest of the hidden flags below (to group well with the
    // other flags).
    _defineAnalysisArguments(parser, hide: hide);

    parser
      ..addOption('format',
          help: 'Specifies the format in which errors are displayed; the only '
              'currently recognized values are \'json\' and \'machine\'.')
      ..addFlag('version',
          help: 'Print the analyzer version.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('no-hints',
          help: 'Do not show hint results.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('fatal-infos',
          help: 'Treat infos as fatal.', defaultsTo: false, negatable: false)
      ..addFlag('fatal-warnings',
          help: 'Treat non-type warnings as fatal.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('help',
          abbr: 'h',
          help:
              'Display this help message. Add --verbose to show hidden options.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('verbose',
          abbr: 'v',
          defaultsTo: false,
          help: 'Verbose output.',
          negatable: false);

    parser.addFlag('color',
        help: 'Use ansi colors when printing messages.',
        defaultsTo: ansi.terminalSupportsAnsi(),
        hide: hide);

    // Hidden flags.
    if (!hide) {
      parser.addSeparator('Less frequently used flags:');
    }

    parser
      ..addFlag('batch',
          help: 'Read commands from standard input (for testing).',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag(_ignoreUnrecognizedFlagsFlag,
          help: 'Ignore unrecognized command line flags.',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addOption(_defaultLanguageVersionOption,
          help: 'The default language version when it is not specified via '
              'other ways (internal, tests only).',
          hide: false)
      ..addFlag('disable-cache-flushing', defaultsTo: false, hide: hide)
      ..addOption('x-perf-report',
          help: 'Writes a performance report to the given file (experimental).',
          hide: hide)
      ..addOption('x-package-warnings-prefix',
          help:
              'Show warnings from package: imports that match the given prefix (deprecated).',
          hide: hide)
      ..addFlag('enable-conditional-directives',
          help:
              'deprecated -- Enable support for conditional directives (DEP 40).',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('show-package-warnings',
          help: 'Show warnings from package: imports (deprecated).',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('sdk-warnings',
          help: 'Show warnings from SDK imports (deprecated).',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('log',
          help: 'Log additional messages and exceptions.',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('enable_type_checks',
          help: 'Check types in constant evaluation (deprecated).',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('use-analysis-driver-memory-byte-store',
          help: 'Use memory byte store, not the file system cache.',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('fatal-hints',
          help: 'Treat hints as fatal (deprecated: use --fatal-infos).',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('fatal-lints',
          help: 'Treat lints as fatal.',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addFlag('package-warnings',
          help: 'Show warnings from package: imports (deprecated).',
          defaultsTo: false,
          negatable: false,
          hide: hide)
      ..addMultiOption('url-mapping',
          help: '--url-mapping=libraryUri,/path/to/library.dart directs the '
              'analyzer to use "library.dart" as the source for an import '
              'of "libraryUri".',
          splitCommas: false,
          hide: hide)
      ..addFlag('train-snapshot',
          help: 'Analyze the given source for the purposes of training a '
              'dartanalyzer snapshot.',
          hide: hide,
          negatable: false);

    try {
      if (args.contains('--$_ignoreUnrecognizedFlagsFlag')) {
        args = filterUnknownArguments(args, parser);
      }
      var results = parser.parse(args);

      // Help requests.
      if (cast(results['help'])) {
        _showUsage(parser, fromHelp: true);
        exitHandler(0);
        return null; // Only reachable in testing.
      }

      // Batch mode and input files.
      if (cast(results['batch'])) {
        if (results.rest.isNotEmpty) {
          errorSink.writeln('No source files expected in the batch mode.');
          _showUsage(parser);
          exitHandler(15);
          return null; // Only reachable in testing.
        }
      } else if (cast(results['version'])) {
        outSink.writeln('$_binaryName version ${_getVersion()}');
        exitHandler(0);
        return null; // Only reachable in testing.
      } else {
        if (results.rest.isEmpty) {
          _showUsage(parser, fromHelp: true);
          exitHandler(15);
          return null; // Only reachable in testing.
        }
      }

      if (results.wasParsed('strong')) {
        errorSink.writeln(
            'Note: the --strong flag is deprecated and will be removed in an '
            'future release.\n');
      }
      if (results.wasParsed(_enableExperimentOption)) {
        var names =
            (results[_enableExperimentOption] as List).cast<String>().toList();
        var errorFound = false;
        for (var validationResult in validateFlags(names)) {
          if (validationResult.isError) {
            errorFound = true;
          }
          var kind = validationResult.isError ? 'ERROR' : 'WARNING';
          errorSink.writeln('$kind: ${validationResult.message}');
        }
        if (errorFound) {
          _showUsage(parser);
          exitHandler(15);
          return null; // Only reachable in testing.
        }
      }

      return CommandLineOptions._fromArgs(resourceProvider, results);
    } on FormatException catch (e) {
      errorSink.writeln(e.message);
      _showUsage(parser);
      exitHandler(15);
      return null; // Only reachable in testing.
    }
  }

  static void _showUsage(ArgParser parser, {bool fromHelp = false}) {
    errorSink.writeln(
        'Usage: $_binaryName [options...] <directory or list of files>');

    errorSink.writeln('');
    errorSink.writeln(parser.usage);

    errorSink.writeln('');
    errorSink.writeln('''
Run "dartanalyzer -h -v" for verbose help output, including less commonly used options.
For more information, see https://dart.dev/tools/dartanalyzer.\n''');
  }
}
