// 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:path/path.dart' as path;

// Path to root of the flutter/engine repository containing this script.
final String _engineRoot = path.dirname(path.dirname(path.dirname(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,
    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,
  }) {
    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),
    );
  }

  /// Builds an instance of [Options] from the given `arguments`.
  factory Options.fromCommandLine(
    List<String> arguments, {
    StringSink? errSink,
  }) {
    final ArgResults argResults = _argParser.parse(arguments);

    String? buildCommandsPath = argResults['compile-commands'] as String?;
    // path/to/engine/src/out/variant/compile_commands.json
    buildCommandsPath ??= path.join(
      argResults['src-dir'] as String,
      'out',
      argResults['target-variant'] as String,
      'compile_commands.json',
    );
    final io.File buildCommands = io.File(buildCommandsPath);
    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);
    }
    return Options._fromArgResults(
      argResults,
      buildCommandsPath: buildCommands,
      errSink: errSink,
    );
  }

  static final ArgParser _argParser = 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(
      '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 containing compile_commands.json '
            'created by running "tools/gn". Cannot be used with --compile-commands.',
      valueHelp: 'host_debug|android_debug_unopt|ios_debug|ios_debug_sim_unopt',
      defaultsTo: 'host_debug',
    )
    ..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. Cannot be used with --compile-commands.',
      valueHelp: 'path/to/engine/src',
      defaultsTo: path.dirname(_engineRoot),
    )
    ..addOption(
      'checks',
      help: 'Perform the given checks on the code. Defaults to the empty '
            'string, indicating all checks should be performed.',
      defaultsTo: '',
    );

  /// 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 root of the flutter/engine repository.
  final io.Directory repoPath = io.Directory(_engineRoot);

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

  /// 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}) {
    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.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.";
    }

    return null;
  }
}
