// Copyright 2014 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 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:flutter_tools/executable.dart' as executable;
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';

import '../src/common.dart';
import '../src/context.dart';
import '../src/testbed.dart';
import 'runner/utils.dart';

void main() {
  setUpAll(() {
    Cache.disableLocking();
  });

  tearDownAll(() {
    Cache.enableLocking();
  });

  test('Help for command line arguments is consistently styled and complete', () => Testbed().run(() {
    final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);
    executable.generateCommands(
      verboseHelp: true,
      verbose: true,
    ).forEach(runner.addCommand);
    verifyCommandRunner(runner);
    for (final Command<void> command in runner.commands.values) {
      if (command.name == 'analyze') {
        final AnalyzeCommand analyze = command as AnalyzeCommand;
        expect(analyze.allProjectValidators().length, 2);
      }
    }
  }));

  testUsingContext('Global arg results are available in FlutterCommands', () async {
    final DummyFlutterCommand command = DummyFlutterCommand(
      commandFunction: () async {
        return const FlutterCommandResult(ExitStatus.success);
      },
    );

    final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);

    runner.addCommand(command);
    await runner.run(<String>['dummy', '--${FlutterGlobalOptions.kContinuousIntegrationFlag}']);

    expect(command.globalResults, isNotNull);
    expect(command.boolArg(FlutterGlobalOptions.kContinuousIntegrationFlag, global: true), true);
  });

  testUsingContext('Global arg results are available in FlutterCommands sub commands', () async {
    final DummyFlutterCommand command = DummyFlutterCommand(
      commandFunction: () async {
        return const FlutterCommandResult(ExitStatus.success);
      },
    );

    final DummyFlutterCommand subcommand = DummyFlutterCommand(
      name: 'sub',
      commandFunction: () async {
        return const FlutterCommandResult(ExitStatus.success);
      },
    );

    command.addSubcommand(subcommand);

    final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);

    runner.addCommand(command);
    runner.addCommand(subcommand);
    await runner.run(<String>['dummy', 'sub', '--${FlutterGlobalOptions.kContinuousIntegrationFlag}']);

    expect(subcommand.globalResults, isNotNull);
    expect(subcommand.boolArg(FlutterGlobalOptions.kContinuousIntegrationFlag, global: true), true);
  });

  testUsingContext('bool? safe argResults', () async {
    final DummyFlutterCommand command = DummyFlutterCommand(
      commandFunction: () async {
        return const FlutterCommandResult(ExitStatus.success);
      },
    );
    final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);
    command.argParser.addFlag('key');
    command.argParser.addFlag('key-false');
    // argResults will be null at this point, if attempt to read them is made,
    // exception `Null check operator used on a null value` would be thrown.
    expect(() => command.boolArg('key'), throwsA(const TypeMatcher<TypeError>()));

    runner.addCommand(command);
    await runner.run(<String>['dummy', '--key']);

    expect(command.boolArg('key'), true);
    expect(() => command.boolArg('non-existent'), throwsArgumentError);

    expect(command.boolArg('key'), true);
    expect(() => command.boolArg('non-existent'), throwsA(const TypeMatcher<ArgumentError>()));

    expect(command.boolArg('key-false'), false);
    expect(command.boolArg('key-false'), false);
  });

  testUsingContext('String? safe argResults', () async {
    final DummyFlutterCommand command = DummyFlutterCommand(
      commandFunction: () async {
        return const FlutterCommandResult(ExitStatus.success);
      },
    );
    final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);
    command.argParser.addOption('key');
    // argResults will be null at this point, if attempt to read them is made,
    // exception `Null check operator used on a null value` would be thrown
    expect(() => command.stringArg('key'), throwsA(const TypeMatcher<TypeError>()));

    runner.addCommand(command);
    await runner.run(<String>['dummy', '--key=value']);

    expect(command.stringArg('key'), 'value');
    expect(() => command.stringArg('non-existent'), throwsArgumentError);

    expect(command.stringArg('key'), 'value');
    expect(() => command.stringArg('non-existent'), throwsA(const TypeMatcher<ArgumentError>()));
  });

  testUsingContext('List<String> safe argResults', () async {
    final DummyFlutterCommand command = DummyFlutterCommand(
      commandFunction: () async {
        return const FlutterCommandResult(ExitStatus.success);
      },
    );
    final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: true);
    command.argParser.addMultiOption(
      'key',
      allowed: <String>['a', 'b', 'c'],
    );
    // argResults will be null at this point, if attempt to read them is made,
    // exception `Null check operator used on a null value` would be thrown.
    expect(() => command.stringsArg('key'), throwsA(const TypeMatcher<TypeError>()));

    runner.addCommand(command);
    await runner.run(<String>['dummy', '--key', 'a']);

    // throws error when trying to parse non-existent key.
    expect(() => command.stringsArg('non-existent'), throwsA(const TypeMatcher<ArgumentError>()));

    expect(command.stringsArg('key'), <String>['a']);

    await runner.run(<String>['dummy', '--key', 'a', '--key', 'b']);
    expect(command.stringsArg('key'), <String>['a', 'b']);

    await runner.run(<String>['dummy']);
    expect(command.stringsArg('key'), <String>[]);
  });
}

void verifyCommandRunner(CommandRunner<Object?> runner) {
  expect(runner.argParser, isNotNull, reason: '${runner.runtimeType} has no argParser');
  expect(runner.argParser.allowsAnything, isFalse, reason: '${runner.runtimeType} allows anything');
  expect(runner.argParser.allowTrailingOptions, isFalse, reason: '${runner.runtimeType} allows trailing options');
  verifyOptions(null, runner.argParser.options.values);
  runner.commands.values.forEach(verifyCommand);
}

void verifyCommand(Command<Object?> runner) {
  expect(runner.argParser, isNotNull, reason: 'command ${runner.name} has no argParser');
  verifyOptions(runner.name, runner.argParser.options.values);

  final String firstDescriptionLine = runner.description.split('\n').first;
  expect(firstDescriptionLine, matches(_allowedTrailingPatterns), reason: "command ${runner.name}'s description does not end with the expected single period that a full sentence should end with");

  if (!runner.hidden && runner.parent == null) {
    expect(
      runner.category,
      anyOf(
        FlutterCommandCategory.sdk,
        FlutterCommandCategory.project,
        FlutterCommandCategory.tools,
      ),
      reason: "top-level command ${runner.name} doesn't have a valid category",
    );
  }

  runner.subcommands.values.forEach(verifyCommand);
}

// Patterns for arguments names.
final RegExp _allowedArgumentNamePattern = RegExp(r'^([-a-z0-9]+)$');
final RegExp _allowedArgumentNamePatternForPrecache = RegExp(r'^([-a-z0-9_]+)$');
final RegExp _bannedArgumentNamePattern = RegExp(r'-uri$');

// Patterns for help messages.
final RegExp _bannedLeadingPatterns = RegExp(r'^[-a-z]', multiLine: true);
final RegExp _allowedTrailingPatterns = RegExp(r'([^ ]([^.^!^:][.!:])\)?|: https?://[^ ]+[^.]|^)$');
final RegExp _bannedQuotePatterns = RegExp(r" '|' |'\.|\('|'\)|`");
final RegExp _bannedArgumentReferencePatterns = RegExp(r'[^"=]--[^ ]');
final RegExp _questionablePatterns = RegExp(r'[a-z]\.[A-Z]');
final RegExp _bannedUri = RegExp(r'\b[Uu][Rr][Ii]\b');
final RegExp _nonSecureFlutterDartUrl = RegExp(r'http://([a-z0-9-]+\.)*(flutter|dart)\.dev', caseSensitive: false);
const String _needHelp = "Every option must have help explaining what it does, even if it's "
                         'for testing purposes, because this is the bare minimum of '
                         'documentation we can add just for ourselves. If it is not intended '
                         'for developers, then use "hide: !verboseHelp" to only show the '
                         'help when people run with "--help --verbose".';

const String _header = ' Comment: ';

void verifyOptions(String? command, Iterable<Option> options) {
  String target;
  if (command == null) {
    target = 'the global argument "';
  } else {
    target = '"flutter $command ';
  }
  assert(target.contains('"'));
  for (final Option option in options) {
    // If you think you need to add an exception here, please ask Hixie (but he'll say no).
    if (command == 'precache') {
      expect(option.name, matches(_allowedArgumentNamePatternForPrecache), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (Is it all lowercase?)');
    } else {
      expect(option.name, matches(_allowedArgumentNamePattern), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (Is it all lowercase? Does it use hyphens rather than underscores?)');
    }
    expect(option.name, isNot(matches(_bannedArgumentNamePattern)), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (We use "--foo-url", not "--foo-uri", for example.)');
    // The flag --sound-null-safety is deprecated
    if (option.name != FlutterOptions.kNullSafety && option.name != FlutterOptions.kNullAssertions) {
      expect(option.hide, isFalse, reason: '${_header}Help for $target--${option.name}" is always hidden. $_needHelp');
    }
    expect(option.help, isNotNull, reason: '${_header}Help for $target--${option.name}" has null help. $_needHelp');
    expect(option.help, isNotEmpty, reason: '${_header}Help for $target--${option.name}" has empty help. $_needHelp');
    expect(option.help, isNot(matches(_bannedLeadingPatterns)), reason: '${_header}A line in the help for $target--${option.name}" starts with a lowercase letter. For stylistic consistency, all help messages must start with a capital letter.');
    expect(option.help, isNot(startsWith('(Deprecated')), reason: '${_header}Help for $target--${option.name}" should start with lowercase "(deprecated)" for consistency with other deprecated commands.');
    expect(option.help, isNot(startsWith('(Required')), reason: '${_header}Help for $target--${option.name}" should start with lowercase "(required)" for consistency with other deprecated commands.');
    expect(option.help, isNot(contains('?')), reason: '${_header}Help for $target--${option.name}" has a question mark. Generally we prefer the passive voice for help messages.');
    expect(option.help, isNot(contains('Note:')), reason: '${_header}Help for $target--${option.name}" uses "Note:". See our style guide entry about "empty prose".');
    expect(option.help, isNot(contains('Note that')), reason: '${_header}Help for $target--${option.name}" uses "Note that". See our style guide entry about "empty prose".');
    expect(option.help, isNot(matches(_bannedQuotePatterns)), reason: '${_header}Help for $target--${option.name}" uses single quotes or backticks instead of double quotes in the help message. For consistency we use double quotes throughout.');
    expect(option.help, isNot(matches(_questionablePatterns)), reason: '${_header}Help for $target--${option.name}" may have a typo. (If it does not you may have to update args_test.dart, sorry. Search for "_questionablePatterns")');
    if (option.defaultsTo != null) {
      expect(option.help, isNot(contains('Default')), reason: '${_header}Help for $target--${option.name}" mentions the default value but that is redundant with the defaultsTo option which is also specified (and preferred).');

      final Map<String, String>? allowedHelp = option.allowedHelp;
      if (allowedHelp != null) {
        for (final String allowedValue in allowedHelp.keys) {
          expect(
            allowedHelp[allowedValue],
            isNot(anyOf(contains('default'), contains('Default'))),
            reason: '${_header}Help for $target--${option.name} $allowedValue" mentions the default value but that is redundant with the defaultsTo option which is also specified (and preferred).',
          );
        }
      }
    }
    expect(option.help, isNot(matches(_bannedArgumentReferencePatterns)), reason: '${_header}Help for $target--${option.name}" contains the string "--" in an unexpected way. If it\'s trying to mention another argument, it should be quoted, as in "--foo".');
    for (final String line in option.help!.split('\n')) {
      if (!line.startsWith('    ')) {
        expect(line, isNot(contains('  ')), reason: '${_header}Help for $target--${option.name}" has excessive whitespace (check e.g. for double spaces after periods or round line breaks in the source).');
        expect(line, matches(_allowedTrailingPatterns), reason: '${_header}A line in the help for $target--${option.name}" does not end with the expected period that a full sentence should end with. (If the help ends with a URL, place it after a colon, don\'t leave a trailing period; if it\'s sample code, prefix the line with four spaces.)');
      }
    }
    expect(option.help, isNot(endsWith(':')), reason: '${_header}Help for $target--${option.name}" ends with a colon, which seems unlikely to be correct.');
    expect(option.help, isNot(contains(_bannedUri)), reason: '${_header}Help for $target--${option.name}" uses the term "URI" rather than "URL".');
    expect(option.help, isNot(contains(_nonSecureFlutterDartUrl)), reason: '${_header}Help for $target--${option.name}" links to a non-secure ("http") version of a Flutter or Dart site.');
    // TODO(ianh): add some checking for embedded URLs to make sure we're consistent on how we format those.
    // TODO(ianh): arguably we should ban help text that starts with "Whether to..." since by definition a flag is to enable a feature, so the "whether to" is redundant.
  }
}
