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

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

  /// 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(
      '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);

  /// Arguments to plumb through to clang-tidy formatted as a command line
  /// argument.
  final String checksArg;

  /// Check arguments to plumb through to clang-tidy.
  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;
  }
}
