// 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.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,
      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(
      '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 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] [--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 (!buildCommandsPath.existsSync()) {
      return "ERROR: Build commands path ${buildCommandsPath.absolute.path} doesn't exist.";
    }

    return null;
  }
}
