// 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/analysis_options/analysis_options.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
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';

const _analysisOptionsFileOption = 'options';
const _binaryName = 'dartanalyzer';
const _defineVariableOption = 'D';
const _enableExperimentOption = 'enable-experiment';
const _enableInitializingFormalAccessFlag = 'initializing-formal-access';
const _ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags';
const _packagesOption = 'packages';
const _sdkPathOption = 'dart-sdk';

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

/// 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 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;

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

  /// 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].
  new _fromArgs(ResourceProvider resourceProvider, ArgResults args)
    : _argResults = args,
      dartSdkPath = args.option(_sdkPathOption),
      disableCacheFlushing = args.flag('disable-cache-flushing'),
      displayVersion = args.flag('version'),
      ignoreUnrecognizedFlags = args.flag(_ignoreUnrecognizedFlagsFlag),
      log = args.flag('log'),
      jsonFormat = args['format'] == 'json',
      machineFormat = args['format'] == 'machine',
      perfReport = args.option('x-perf-report'),
      batchMode = args.flag('batch'),
      sourceFiles = args.rest,
      trainSnapshot = args.flag('train-snapshot'),
      verbose = args.flag('verbose'),
      color = args.flag('color') {
    //
    // File locations.
    //
    defaultAnalysisOptionsPath = _absoluteNormalizedPath(
      resourceProvider,
      args.option(_analysisOptionsFileOption),
    );
    defaultPackagesPath = _absoluteNormalizedPath(
      resourceProvider,
      args.option(_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);
        }
      }
    }
  }

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

  /// Configure the [analysisOptionsBuilder] with flags that the user specified
  /// explicitly. The builder is usually initialized 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 configureAnalysisOptionsBuilder(
    AnalysisOptionsBuilder analysisOptionsBuilder,
  ) {
    if (enabledExperiments.isNotEmpty) {
      analysisOptionsBuilder.contextFeatures = FeatureSet.fromEnableFlags2(
        sdkLanguageVersion: ExperimentStatus.currentVersion,
        flags: enabledExperiments,
      ) as ExperimentStatus;
    }
  }

  /// 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 pathContext = resourceProvider.pathContext;
      var sdkPath = options.dartSdkPath;

      if (sdkPath != null) {
        var normalized = file_paths.absoluteNormalized(pathContext, sdkPath);
        if (!resourceProvider.getFolder(normalized).exists) {
          printAndFail('Invalid Dart SDK path: $sdkPath');
          return null; // Only reachable in testing.
        }
      }

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

      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.addMultiOption(
      _enableExperimentOption,
      help:
          'Enable one or more experimental features. If multiple features '
          'are being added, they should be comma separated.',
      splitCommas: true,
    );

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

  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(
        '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,
      )
      ..addFlag('disable-cache-flushing', defaultsTo: false, hide: hide)
      ..addOption(
        'x-perf-report',
        help: 'Writes a performance report to the given file (experimental).',
        hide: hide,
      )
      ..addFlag(
        'enable-conditional-directives',
        help:
            'deprecated -- Enable support for conditional directives (DEP 40).',
        defaultsTo: false,
        negatable: false,
        hide: hide,
      )
      ..addFlag(
        'log',
        help: 'Log additional messages and exceptions.',
        defaultsTo: false,
        negatable: false,
        hide: hide,
      )
      ..addFlag(
        'use-analysis-driver-memory-byte-store',
        help: 'Use memory byte store, not the file system cache.',
        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 (results.flag('help')) {
        _showUsage(parser, fromHelp: true);
        exitHandler(0);
        return null; // Only reachable in testing.
      }

      // Batch mode and input files.
      if (results.flag('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 (results.flag('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(_enableExperimentOption)) {
        var names = results.multiOption(_enableExperimentOption);
        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''');
  }
}
