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

// @dart = 2.8

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:flutter_tools/executable.dart' as executable;
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';

import '../src/common.dart';
import '../src/testbed.dart';

void main() {
  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);
  }));
}

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);
  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');
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.)');
    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).');

      if (option.allowedHelp != null) {
        for (final String allowedValue in option.allowedHelp.keys) {
          expect(
            option.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".');
    // 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.
  }
}
