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

library analyzer_cli.src.options;

import 'dart:io';

import 'package:analyzer_cli/src/driver.dart';
import 'package:args/args.dart';
import 'package:cli_util/cli_util.dart' show getSdkDir;

const _binaryName = 'dartanalyzer';

/// Shared exit handler.
///
/// *Visible for testing.*
ExitHandler exitHandler = 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 void ExitHandler(int code);

/// Analyzer commandline configuration options.
class CommandLineOptions {
  /// The path to an analysis options file
  final String analysisOptionsFile;

  /// The path to output analysis results when in build mode.
  final String buildAnalysisOutput;

  /// Whether to use build mode.
  final bool buildMode;

  /// Whether to use build mode as a Bazel persistent worker.
  final bool buildModePersistentWorker;

  /// List of summary file paths to use in build mode.
  final List<String> buildSummaryInputs;

  /// Whether to skip analysis when creating summaries in build mode.
  final bool buildSummaryOnly;

  /// Whether to create summaries using only ASTs, i.e. don't perform
  /// resolution.
  final bool buildSummaryOnlyAst;

  /// Whether to use diet parsing, i.e. skip function bodies. We don't need to
  /// analyze function bodies to use summaries during future compilation steps.
  final bool buildSummaryOnlyDiet;

  /// Whether to use exclude informative data from created summaries.
  final bool buildSummaryExcludeInformative;

  /// The path to output the summary when creating summaries in build mode.
  final String buildSummaryOutput;

  /// Whether to output a summary in "fallback mode".
  final bool buildSummaryFallback;

  /// Whether to suppress a nonzero exit code in build mode.
  final bool buildSuppressExitCode;

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

  /// The path to the dart SDK summary file.
  String dartSdkSummaryPath;

  /// A table mapping the names of defined variables to their values.
  final Map<String, String> definedVariables;

  /// Whether to report hints
  final bool disableHints;

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

  /// Whether to enable null-aware operators (DEP 9).
  final bool enableNullAwareOperators;

  /// Whether to strictly follow the specification when generating warnings on
  /// "call" methods (fixes dartbug.com/21938).
  final bool enableStrictCallChecks;

  /// Whether to relax restrictions on mixins (DEP 34).
  final bool enableSuperMixins;

  /// Whether to treat type mismatches found during constant evaluation as
  /// errors.
  final bool enableTypeChecks;

  /// Whether to treat hints as fatal
  final bool hintsAreFatal;

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

  /// Whether to report lints
  final bool lints;

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

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

  /// The path to the root folder of the incremental cache.
  final String incrementalCachePath;

  /// The path to the package root
  final String packageRootPath;

  /// The path to a `.packages` configuration file
  final String packageConfigPath;

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

  /// 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 use strong static checking.
  final bool strongMode;

  /// Whether to treat lints as fatal
  final bool lintsAreFatal;

  /// Initialize options from the given parsed [args].
  CommandLineOptions._fromArgs(
      ArgResults args, Map<String, String> definedVariables)
      : buildAnalysisOutput = args['build-analysis-output'],
        buildMode = args['build-mode'],
        buildModePersistentWorker = args['persistent_worker'],
        buildSummaryFallback = args['build-summary-fallback'],
        buildSummaryInputs = args['build-summary-input'],
        buildSummaryOnly = args['build-summary-only'],
        buildSummaryOnlyAst = args['build-summary-only-ast'],
        buildSummaryOnlyDiet = args['build-summary-only-diet'],
        buildSummaryExcludeInformative =
            args['build-summary-exclude-informative'],
        buildSummaryOutput = args['build-summary-output'],
        buildSuppressExitCode = args['build-suppress-exit-code'],
        dartSdkPath = args['dart-sdk'],
        dartSdkSummaryPath = args['dart-sdk-summary'],
        definedVariables = definedVariables,
        analysisOptionsFile = args['options'],
        disableHints = args['no-hints'],
        displayVersion = args['version'],
        enableNullAwareOperators = args['enable-null-aware-operators'],
        enableStrictCallChecks = args['enable-strict-call-checks'],
        enableSuperMixins = args['supermixin'],
        enableTypeChecks = args['enable_type_checks'],
        hintsAreFatal = args['fatal-hints'],
        ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
        lints = args['lints'],
        log = args['log'],
        machineFormat = args['machine'] || args['format'] == 'machine',
        incrementalCachePath = args['incremental-cache-path'],
        packageConfigPath = args['packages'],
        packageRootPath = args['package-root'],
        perfReport = args['x-perf-report'],
        shouldBatch = args['batch'],
        showPackageWarnings = args['show-package-warnings'] ||
            args['package-warnings'] ||
            args['x-package-warnings-prefix'] != null,
        showPackageWarningsPrefix = args['x-package-warnings-prefix'],
        showSdkWarnings = args['show-sdk-warnings'] || args['warnings'],
        sourceFiles = args.rest,
        warningsAreFatal = args['fatal-warnings'],
        strongMode = args['strong'],
        lintsAreFatal = args['fatal-lints'];

  /// 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(List<String> args,
      [printAndFail(String msg) = printAndFail]) {
    CommandLineOptions options = _parse(args);
    // Check SDK.
    if (!options.buildModePersistentWorker) {
      // Infer if unspecified.
      if (options.dartSdkPath == null) {
        Directory sdkDir = getSdkDir(args);
        if (sdkDir != null) {
          options.dartSdkPath = sdkDir.path;
        }
      }

      var sdkPath = options.dartSdkPath;

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

    // Check package config.
    {
      if (options.packageRootPath != null &&
          options.packageConfigPath != null) {
        printAndFail("Cannot specify both '--package-root' and '--packages.");
        return null; // Only reachable in testing.
      }
    }

    // OK.  Report deprecated options.
    if (options.enableNullAwareOperators) {
      errorSink.writeln(
          "Info: Option '--enable-null-aware-operators' is no longer needed. "
          "Null aware operators are supported by default.");
    }

    // Build mode.
    if (options.buildModePersistentWorker && !options.buildMode) {
      printAndFail('The option --persisten_worker can be used only '
          'together with --build-mode.');
    }
    if (options.buildSummaryOnlyDiet && !options.buildSummaryOnly) {
      printAndFail('The option --build-summary-only-diet can be used only '
          'together with --build-summary-only.');
    }

    return options;
  }

  static String _getVersion() {
    try {
      // This is relative to bin/snapshot, so ../..
      String versionPath =
          Platform.script.resolve('../../version').toFilePath();
      File versionFile = new 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(List<String> args) {
    // Check if the args are in a file (bazel worker mode).
    if (args.last.startsWith('@')) {
      var argsFile = new File(args.last.substring(1));
      args = argsFile.readAsLinesSync();
    }

    args = args.expand((String arg) => arg.split('=')).toList();
    var parser = new CommandLineParser()
      ..addFlag('batch',
          abbr: 'b',
          help: 'Read commands from standard input (for testing).',
          defaultsTo: false,
          negatable: false)
      ..addOption('dart-sdk', help: 'The path to the Dart SDK.')
      ..addOption('dart-sdk-summary',
          help: 'The path to the Dart SDK summary file.', hide: true)
      ..addOption('packages',
          help:
              'Path to the package resolution configuration file, which supplies '
              'a mapping of package names to paths.  This option cannot be '
              'used with --package-root.')
      ..addOption('package-root',
          abbr: 'p',
          help: 'Path to a package root directory (deprecated). This option '
              'cannot be used with --packages.')
      ..addOption('options', help: 'Path to an analysis options file.')
      ..addOption('format',
          help: 'Specifies the format in which errors are displayed.')
      ..addFlag('machine',
          help: 'Print errors in a format suitable for parsing (deprecated).',
          defaultsTo: false,
          negatable: false)
      ..addFlag('version',
          help: 'Print the analyzer version.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('lints',
          help: 'Show lint results.', defaultsTo: false, negatable: false)
      ..addFlag('no-hints',
          help: 'Do not show hint results.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('ignore-unrecognized-flags',
          help: 'Ignore unrecognized command line flags.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('fatal-hints',
          help: 'Treat hints as fatal.', defaultsTo: false, negatable: false)
      ..addFlag('fatal-warnings',
          help: 'Treat non-type warnings as fatal.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('fatal-lints',
          help: 'Treat lints as fatal.', defaultsTo: false, negatable: false)
      ..addFlag('package-warnings',
          help: 'Show warnings from package: imports.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('show-package-warnings',
          help: 'Show warnings from package: imports (deprecated).',
          defaultsTo: false,
          negatable: false)
      ..addFlag('warnings',
          help: 'Show warnings from SDK imports.',
          defaultsTo: false,
          negatable: false)
      ..addFlag('show-sdk-warnings',
          help: 'Show warnings from SDK imports (deprecated).',
          defaultsTo: false,
          negatable: false)
      ..addOption('x-package-warnings-prefix',
          help:
              'Show warnings from package: imports that match the given prefix',
          hide: true)
      ..addOption('x-perf-report',
          help: 'Writes a performance report to the given file (experimental).')
      ..addFlag('help',
          abbr: 'h',
          help: 'Display this help message.',
          defaultsTo: false,
          negatable: false)
      ..addOption('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".',
          allowMultiple: true,
          splitCommas: false)
      //
      // Incremental analysis.
      //
      ..addOption('incremental-cache-path',
          help: 'The path to the folder with information to support '
              'incremental analysis, e.g. summary files, errors, etc.',
          hide: true)
      //
      // Build mode.
      //
      ..addFlag('persistent_worker',
          help: 'Enable Bazel persistent worker mode.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addOption('build-analysis-output',
          help:
              'Specifies the path to the file where analysis results should be written.',
          hide: true)
      ..addFlag('build-mode',
          // TODO(paulberry): add more documentation.
          help: 'Enable build mode.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addOption('build-summary-input',
          help: 'Path to a summary file that contains information from a '
              'previous analysis run.  May be specified multiple times.',
          allowMultiple: true,
          hide: true)
      ..addOption('build-summary-output',
          help: 'Specifies the path to the file where the summary information '
              'should be written.',
          hide: true)
      ..addFlag('build-summary-only',
          help: 'Disable analysis (only generate summaries).',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('build-summary-only-ast',
          help: 'Generate summaries using ASTs.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('build-summary-only-diet',
          help: 'Diet parse function bodies.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('build-summary-exclude-informative',
          help: 'Exclude @informative information (docs, offsets, etc).',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('build-summary-fallback',
          help: 'If outputting a summary, output it in fallback mode.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('build-suppress-exit-code',
          help: 'Exit with code 0 even if errors are found.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      //
      // Hidden flags.
      //
      ..addFlag('enable-async',
          help: 'Enable support for the proposed async feature.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('enable-enum',
          help: 'Enable support for the proposed enum feature.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('enable-conditional-directives',
          help:
              'deprecated -- Enable support for conditional directives (DEP 40).',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('enable-null-aware-operators',
          help: 'Enable support for null-aware operators (DEP 9).',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('enable-strict-call-checks',
          help: 'Fix issue 21938.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('enable-new-task-model',
          help: 'deprecated -- Ennable new task model.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('supermixin',
          help: 'Relax restrictions on mixins (DEP 34).',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('log',
          help: 'Log additional messages and exceptions.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('enable_type_checks',
          help: 'Check types in constant evaluation.',
          defaultsTo: false,
          negatable: false,
          hide: true)
      ..addFlag('strong',
          help: 'Enable strong static checks (https://goo.gl/DqcBsw)');

    try {
      // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061
      args =
          args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList();
      Map<String, String> definedVariables = <String, String>{};
      var results = parser.parse(args, definedVariables);

      // Persistent worker.
      if (args.contains('--persistent_worker')) {
        bool validArgs;
        if (!args.contains('--build-mode')) {
          validArgs = false;
        } else if (args.length == 2) {
          validArgs = true;
        } else if (args.length == 4 && args.contains('--dart-sdk')) {
          validArgs = true;
        } else {
          validArgs = false;
        }
        if (!validArgs) {
          printAndFail('The --persistent_worker flag should be used with and '
              'only with the --build-mode flag, and possibly the --dart-sdk '
              'option. Got: $args');
          return null; // Only reachable in testing.
        }
        return new CommandLineOptions._fromArgs(results, definedVariables);
      }

      // Help requests.
      if (results['help']) {
        _showUsage(parser);
        exitHandler(0);
        return null; // Only reachable in testing.
      }
      // Batch mode and input files.
      if (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 (results['persistent_worker']) {
        if (results.rest.isNotEmpty) {
          errorSink.writeln(
              'No source files expected in the persistent worker mode.');
          _showUsage(parser);
          exitHandler(15);
          return null; // Only reachable in testing.
        }
      } else if (results['version']) {
        outSink.write('$_binaryName version ${_getVersion()}');
        exitHandler(0);
        return null; // Only reachable in testing.
      } else {
        if (results.rest.isEmpty && !results['build-mode']) {
          _showUsage(parser);
          exitHandler(15);
          return null; // Only reachable in testing.
        }
      }
      return new CommandLineOptions._fromArgs(results, definedVariables);
    } on FormatException catch (e) {
      errorSink.writeln(e.message);
      _showUsage(parser);
      exitHandler(15);
      return null; // Only reachable in testing.
    }
  }

  static _showUsage(parser) {
    errorSink
        .writeln('Usage: $_binaryName [options...] <libraries to analyze...>');
    errorSink.writeln(parser.getUsage());
    errorSink.writeln('');
    errorSink.writeln(
        'For more information, see http://www.dartlang.org/tools/analyzer.');
  }
}

/// Commandline argument parser.
///
/// TODO(pq): when the args package supports ignoring unrecognized
/// options/flags, this class can be replaced with a simple [ArgParser]
/// instance.
class CommandLineParser {
  final List<String> _knownFlags;
  final bool _alwaysIgnoreUnrecognized;
  final ArgParser _parser;

  /// Creates a new command line parser.
  CommandLineParser({bool alwaysIgnoreUnrecognized: false})
      : _knownFlags = <String>[],
        _alwaysIgnoreUnrecognized = alwaysIgnoreUnrecognized,
        _parser = new ArgParser(allowTrailingOptions: true);

  ArgParser get parser => _parser;

  /// Defines a flag.
  /// See [ArgParser.addFlag()].
  void addFlag(String name,
      {String abbr,
      String help,
      bool defaultsTo: false,
      bool negatable: true,
      void callback(bool value),
      bool hide: false}) {
    _knownFlags.add(name);
    _parser.addFlag(name,
        abbr: abbr,
        help: help,
        defaultsTo: defaultsTo,
        negatable: negatable,
        callback: callback,
        hide: hide);
  }

  /// Defines a value-taking option.
  /// See [ArgParser.addOption()].
  void addOption(String name,
      {String abbr,
      String help,
      List<String> allowed,
      Map<String, String> allowedHelp,
      String defaultsTo,
      void callback(value),
      bool allowMultiple: false,
      bool splitCommas,
      bool hide: false}) {
    _knownFlags.add(name);
    _parser.addOption(name,
        abbr: abbr,
        help: help,
        allowed: allowed,
        allowedHelp: allowedHelp,
        defaultsTo: defaultsTo,
        callback: callback,
        allowMultiple: allowMultiple,
        splitCommas: splitCommas,
        hide: hide);
  }

  /// Generates a string displaying usage information for the defined options.
  /// See [ArgParser.usage].
  String getUsage() => _parser.usage;

  /// Parses [args], a list of command-line arguments, matches them against the
  /// flags and options defined by this parser, and returns the result. The
  /// values of any defined variables are captured in the given map.
  /// See [ArgParser].
  ArgResults parse(List<String> args, Map<String, String> definedVariables) =>
      _parser.parse(
          _filterUnknowns(parseDefinedVariables(args, definedVariables)));

  List<String> parseDefinedVariables(
      List<String> args, Map<String, String> definedVariables) {
    int count = args.length;
    List<String> remainingArgs = <String>[];
    for (int i = 0; i < count; i++) {
      String arg = args[i];
      if (arg == '--') {
        while (i < count) {
          remainingArgs.add(args[i++]);
        }
      } else if (arg.startsWith("-D")) {
        definedVariables[arg.substring(2)] = args[++i];
      } else {
        remainingArgs.add(arg);
      }
    }
    return remainingArgs;
  }

  List<String> _filterUnknowns(List<String> args) {
    // Only filter args if the ignore flag is specified, or if
    // _alwaysIgnoreUnrecognized was set to true.
    if (_alwaysIgnoreUnrecognized ||
        args.contains('--ignore-unrecognized-flags')) {
      //TODO(pquitslund): replace w/ the following once library skew issues are
      // sorted out
      //return args.where((arg) => !arg.startsWith('--') ||
      //  _knownFlags.contains(arg.substring(2)));

      // Filter all unrecognized flags and options.
      List<String> filtered = <String>[];
      for (int i = 0; i < args.length; ++i) {
        String arg = args[i];
        if (arg.startsWith('--') && arg.length > 2) {
          String option = arg.substring(2);
          // strip the last '=value'
          int equalsOffset = option.lastIndexOf('=');
          if (equalsOffset != -1) {
            option = option.substring(0, equalsOffset);
          }
          // Check the option
          if (!_knownFlags.contains(option)) {
            //"eat" params by advancing to the next flag/option
            i = _getNextFlagIndex(args, i);
          } else {
            filtered.add(arg);
          }
        } else {
          filtered.add(arg);
        }
      }

      return filtered;
    } else {
      return args;
    }
  }

  int _getNextFlagIndex(args, i) {
    for (; i < args.length; ++i) {
      if (args[i].startsWith('--')) {
        return i;
      }
    }
    return i;
  }
}
