// Copyright 2013 The Flutter Authors. 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 show Directory, File, Platform, stderr;

import 'package:args/args.dart';
import 'package:engine_repo_tools/engine_repo_tools.dart';
import 'package:path/path.dart' as path;

final Engine _engineRoot = Engine.findWithin(path.dirname(path.fromUri(io.Platform.script)));

/// Adds warnings as errors for only specific runs.  This is helpful if migrating one platform at a time.
String? _platformSpecificWarningsAsErrors(ArgResults options) {
  if (options['target-variant'] == 'host_debug' && io.Platform.isMacOS) {
    return options['mac-host-warnings-as-errors'] as String?;
  }
  return null;
}


/// A class for organizing the options to the Engine linter, and the files
/// that it operates on.
class Options {
  /// Builds an instance of [Options] from the arguments.
  Options({
    required this.buildCommandsPath,
    this.help = false,
    this.verbose = false,
    this.checksArg = '',
    this.lintAll = false,
    this.lintHead = false,
    this.fix = false,
    this.errorMessage,
    this.warningsAsErrors,
    this.shardId,
    this.shardCommandsPaths = const <io.File>[],
    this.enableCheckProfile = false,
    StringSink? errSink,
  }) : checks = checksArg.isNotEmpty ? '--checks=$checksArg' : null,
       _errSink = errSink ?? io.stderr;

  factory Options._error(
    String message, {
    StringSink? errSink,
  }) {
    return Options(
      errorMessage: message,
      buildCommandsPath: io.File('none'),
      errSink: errSink,
    );
  }

  factory Options._help({
    StringSink? errSink,
  }) {
    return Options(
      help: true,
      buildCommandsPath: io.File('none'),
      errSink: errSink,
    );
  }

  /// Builds an [Options] instance with an [ArgResults] instance.
  factory Options._fromArgResults(
    ArgResults options, {
    required io.File buildCommandsPath,
    StringSink? errSink,
    required List<io.File> shardCommandsPaths,
    int? shardId,
  }) {
    return Options(
      help: options['help'] as bool,
      verbose: options['verbose'] as bool,
      buildCommandsPath: buildCommandsPath,
      checksArg: options.wasParsed('checks') ? options['checks'] as String : '',
      lintAll: io.Platform.environment['FLUTTER_LINT_ALL'] != null ||
               options['lint-all'] as bool,
      lintHead: options['lint-head'] as bool,
      fix: options['fix'] as bool,
      errSink: errSink,
      warningsAsErrors: _platformSpecificWarningsAsErrors(options),
      shardCommandsPaths: shardCommandsPaths,
      shardId: shardId,
      enableCheckProfile: options['enable-check-profile'] as bool,
    );
  }

  /// Builds an instance of [Options] from the given `arguments`.
  factory Options.fromCommandLine(
    List<String> arguments, {
    StringSink? errSink,
    Engine? engine,
  }) {
    // TODO(matanlurey): Refactor this further, ideally moving all of the engine
    // resolution logic (i.e. --src-dir, --target-variant, --compile-commands)
    // into a separate method, and perhaps also adding `engine.output(name)`
    // to engine_repo_tools instead of path manipulation inlined below.
    final ArgResults argResults = _argParser(defaultEngine: engine).parse(arguments);

    String? buildCommandsPath = argResults['compile-commands'] as String?;

    String variantToBuildCommandsFilePath(String variant) =>
      path.join(
        argResults['src-dir'] as String,
        'out',
        variant,
        'compile_commands.json',
      );
    // path/to/engine/src/out/variant/compile_commands.json
    buildCommandsPath ??= variantToBuildCommandsFilePath(argResults['target-variant'] as String);
    final io.File buildCommands = io.File(buildCommandsPath);
    final List<io.File> shardCommands =
        (argResults['shard-variants'] as String? ?? '')
            .split(',')
            .where((String element) => element.isNotEmpty)
            .map((String variant) =>
                io.File(variantToBuildCommandsFilePath(variant)))
            .toList();
    final String? message = _checkArguments(argResults, buildCommands);
    if (message != null) {
      return Options._error(message, errSink: errSink);
    }
    if (argResults['help'] as bool) {
      return Options._help(errSink: errSink);
    }
    final String? shardIdString = argResults['shard-id'] as String?;
    final int? shardId = shardIdString == null ? null : int.parse(shardIdString);
    if (shardId != null && (shardId > shardCommands.length || shardId < 0)) {
      return Options._error('Invalid shard-id value: $shardId.', errSink: errSink);
    }
    return Options._fromArgResults(
      argResults,
      buildCommandsPath: buildCommands,
      errSink: errSink,
      shardCommandsPaths: shardCommands,
      shardId: shardId,
    );
  }

  static ArgParser _argParser({required Engine? defaultEngine}) {
    defaultEngine ??= _engineRoot;
    final io.Directory? latestBuild = defaultEngine.latestOutput()?.path;
    return ArgParser()
      ..addFlag(
        'help',
        abbr: 'h',
        help: 'Print help.',
        negatable: false,
      )
      ..addFlag(
        'lint-all',
        help: 'Lint all of the sources, regardless of FLUTTER_NOLINT.',
      )
      ..addFlag(
        'lint-head',
        help: 'Lint files changed in the tip-of-tree commit.',
      )
      ..addFlag(
        'fix',
        help: 'Apply suggested fixes.',
      )
      ..addFlag(
        'verbose',
        help: 'Print verbose output.',
      )
      ..addOption(
        'shard-id',
        help: 'When used with the shard-commands option this identifies which shard will execute.',
        valueHelp: 'A number less than 1 + the number of shard-commands arguments.',
      )
      ..addOption(
        'shard-variants',
        help: 'Comma separated list of other targets, this invocation '
              'will only execute a subset of the intersection and the difference of the '
              'compile commands. Use with `shard-id`.'
      )
      ..addOption(
        'compile-commands',
        help: 'Use the given path as the source of compile_commands.json. This '
              'file is created by running "tools/gn". Cannot be used with --target-variant '
              'or --src-dir.',
      )
      ..addOption(
        'target-variant',
        aliases: <String>['variant'],
        help: 'The engine variant directory name containing compile_commands.json '
              'created by running "tools/gn".\n\nIf not provided, the default is '
              'the latest build in the engine defined by --src-dir (or the '
              'default path, see --src-dir for details).\n\n'
              'Cannot be used with --compile-commands.',
        valueHelp: 'host_debug|android_debug_unopt|ios_debug|ios_debug_sim_unopt',
        defaultsTo: latestBuild == null ? 'host_debug' : path.basename(latestBuild.path),
      )
      ..addOption('mac-host-warnings-as-errors',
          help:
              'checks that will be treated as errors when running debug_host on mac.')
      ..addOption(
        'src-dir',
        help:
              'Path to the engine src directory.\n\n'
              'If not provided, the default is the engine root directory that '
              'contains the `clang_tidy` tool.\n\n'
              'Cannot be used with --compile-commands.',
        valueHelp: 'path/to/engine/src',
        defaultsTo: _engineRoot.srcDir.path,
      )
      ..addOption(
        'checks',
        help: 'Perform the given checks on the code. Defaults to the empty '
              'string, indicating all checks should be performed.',
        defaultsTo: '',
      )
      ..addFlag(
        'enable-check-profile',
        help: 'Enable per-check timing profiles and print a report to stderr.',
        negatable: false,
      );
  }

  /// Whether to print a help message and exit.
  final bool help;

  /// Whether to run with verbose output.
  final bool verbose;

  /// The location of the compile_commands.json file.
  final io.File buildCommandsPath;

  /// The location of shard compile_commands.json files.
  final List<io.File> shardCommandsPaths;

  /// The identifier of the shard.
  final int? shardId;

  /// The root of the flutter/engine repository.
  final io.Directory repoPath = _engineRoot.flutterDir;

  /// Argument sent as `warnings-as-errors` to clang-tidy.
  final String? warningsAsErrors;

  /// Checks argument as supplied to the command-line.
  final String checksArg;

  /// Check argument to be supplied to the clang-tidy subprocess.
  final String? checks;

  /// Whether all files should be linted.
  final bool lintAll;

  /// Whether to lint only files changed in the tip-of-tree commit.
  final bool lintHead;

  /// Whether checks should apply available fix-ups to the working copy.
  final bool fix;

  /// Whether to enable per-check timing profiles and print a report to stderr.
  final bool enableCheckProfile;

  /// If there was a problem with the command line arguments, this string
  /// contains the error message.
  final String? errorMessage;

  final StringSink _errSink;

  /// Print command usage with an additional message.
  void printUsage({String? message, required Engine? engine}) {
    if (message != null) {
      _errSink.writeln(message);
    }
    _errSink.writeln(
      'Usage: bin/main.dart [--help] [--lint-all] [--lint-head] [--fix] [--verbose] '
      '[--diff-branch] [--target-variant variant] [--src-dir path/to/engine/src]',
    );
    _errSink.writeln(_argParser(defaultEngine: engine).usage);
  }

  /// Command line argument validation.
  static String? _checkArguments(ArgResults argResults, io.File buildCommandsPath) {
    if (argResults.wasParsed('help')) {
      return null;
    }

    final bool compileCommandsParsed = argResults.wasParsed('compile-commands');
    if (compileCommandsParsed && argResults.wasParsed('target-variant')) {
      return 'ERROR: --compile-commands option cannot be used with --target-variant.';
    }

    if (compileCommandsParsed && argResults.wasParsed('src-dir')) {
      return 'ERROR: --compile-commands option cannot be used with --src-dir.';
    }

    if (argResults.wasParsed('lint-all') && argResults.wasParsed('lint-head')) {
      return 'ERROR: At most one of --lint-all and --lint-head can be passed.';
    }

    if (!buildCommandsPath.existsSync()) {
      return "ERROR: Build commands path ${buildCommandsPath.absolute.path} doesn't exist.";
    }

    if (argResults.wasParsed('shard-variants') && !argResults.wasParsed('shard-id')) {
      return 'ERROR: a `shard-id` must be specified with `shard-variants`.';
    }

    return null;
  }
}
