// 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 'package:file/file.dart';
import 'package:git/git.dart';
import 'package:platform/platform.dart';
import 'package:yaml/yaml.dart';

import 'common/core.dart';
import 'common/package_looping_command.dart';
import 'common/process_runner.dart';
import 'common/repository_package.dart';

/// A command to enforce README conventions across the repository.
class ReadmeCheckCommand extends PackageLoopingCommand {
  /// Creates an instance of the README check command.
  ReadmeCheckCommand(
    Directory packagesDir, {
    ProcessRunner processRunner = const ProcessRunner(),
    Platform platform = const LocalPlatform(),
    GitDir? gitDir,
  }) : super(
          packagesDir,
          processRunner: processRunner,
          platform: platform,
          gitDir: gitDir,
        ) {
    argParser.addFlag(_requireExcerptsArg,
        help: 'Require that Dart code blocks be managed by code-excerpt.');
  }

  static const String _requireExcerptsArg = 'require-excerpts';

  // Standardized capitalizations for platforms that a plugin can support.
  static const Map<String, String> _standardPlatformNames = <String, String>{
    'android': 'Android',
    'ios': 'iOS',
    'linux': 'Linux',
    'macos': 'macOS',
    'web': 'Web',
    'windows': 'Windows',
  };

  @override
  final String name = 'readme-check';

  @override
  final String description =
      'Checks that READMEs follow repository conventions.';

  @override
  bool get hasLongOutput => false;

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    final List<String> errors = _validateReadme(package.readmeFile,
        mainPackage: package, isExample: false);
    for (final RepositoryPackage packageToCheck in package.getExamples()) {
      errors.addAll(_validateReadme(packageToCheck.readmeFile,
          mainPackage: package, isExample: true));
    }

    // If there's an example/README.md for a multi-example package, validate
    // that as well, as it will be shown on pub.dev.
    final Directory exampleDir = package.directory.childDirectory('example');
    final File exampleDirReadme = exampleDir.childFile('README.md');
    if (exampleDir.existsSync() && !isPackage(exampleDir)) {
      errors.addAll(_validateReadme(exampleDirReadme,
          mainPackage: package, isExample: true));
    }

    return errors.isEmpty
        ? PackageResult.success()
        : PackageResult.fail(errors);
  }

  List<String> _validateReadme(File readme,
      {required RepositoryPackage mainPackage, required bool isExample}) {
    if (!readme.existsSync()) {
      if (isExample) {
        print('${indentation}No README for '
            '${getRelativePosixPath(readme.parent, from: mainPackage.directory)}');
        return <String>[];
      } else {
        printError('${indentation}No README found at '
            '${getRelativePosixPath(readme, from: mainPackage.directory)}');
        return <String>['Missing README.md'];
      }
    }

    print('${indentation}Checking '
        '${getRelativePosixPath(readme, from: mainPackage.directory)}...');

    final List<String> readmeLines = readme.readAsLinesSync();
    final List<String> errors = <String>[];

    final String? blockValidationError = _validateCodeBlocks(readmeLines);
    if (blockValidationError != null) {
      errors.add(blockValidationError);
    }

    if (_containsTemplateBoilerplate(readmeLines)) {
      printError('${indentation}The boilerplate section about getting started '
          'with Flutter should not be left in.');
      errors.add('Contains template boilerplate');
    }

    // Check if this is the main readme for a plugin, and if so enforce extra
    // checks.
    if (!isExample) {
      final Pubspec pubspec = mainPackage.parsePubspec();
      final bool isPlugin = pubspec.flutter?['plugin'] != null;
      if (isPlugin && (!mainPackage.isFederated || mainPackage.isAppFacing)) {
        final String? error = _validateSupportedPlatforms(readmeLines, pubspec);
        if (error != null) {
          errors.add(error);
        }
      }
    }

    return errors;
  }

  /// Validates that code blocks (``` ... ```) follow repository standards.
  String? _validateCodeBlocks(List<String> readmeLines) {
    final RegExp codeBlockDelimiterPattern = RegExp(r'^\s*```\s*([^ ]*)\s*');
    final List<int> missingLanguageLines = <int>[];
    final List<int> missingExcerptLines = <int>[];
    bool inBlock = false;
    for (int i = 0; i < readmeLines.length; ++i) {
      final RegExpMatch? match =
          codeBlockDelimiterPattern.firstMatch(readmeLines[i]);
      if (match == null) {
        continue;
      }
      if (inBlock) {
        inBlock = false;
        continue;
      }
      inBlock = true;

      final int humanReadableLineNumber = i + 1;

      // Ensure that there's a language tag.
      final String infoString = match[1] ?? '';
      if (infoString.isEmpty) {
        missingLanguageLines.add(humanReadableLineNumber);
        continue;
      }

      // Check for code-excerpt usage if requested.
      if (getBoolArg(_requireExcerptsArg) && infoString == 'dart') {
        const String excerptTagStart = '<?code-excerpt ';
        if (i == 0 || !readmeLines[i - 1].trim().startsWith(excerptTagStart)) {
          missingExcerptLines.add(humanReadableLineNumber);
        }
      }
    }

    String? errorSummary;

    if (missingLanguageLines.isNotEmpty) {
      for (final int lineNumber in missingLanguageLines) {
        printError('${indentation}Code block at line $lineNumber is missing '
            'a language identifier.');
      }
      printError(
          '\n${indentation}For each block listed above, add a language tag to '
          'the opening block. For instance, for Dart code, use:\n'
          '${indentation * 2}```dart\n');
      errorSummary = 'Missing language identifier for code block';
    }

    if (missingExcerptLines.isNotEmpty) {
      for (final int lineNumber in missingExcerptLines) {
        printError('${indentation}Dart code block at line $lineNumber is not '
            'managed by code-excerpt.');
      }
      printError(
          '\n${indentation}For each block listed above, add <?code-excerpt ...> '
          'tag on the previous line, and ensure that a build.excerpt.yaml is '
          'configured for the source example.\n');
      errorSummary ??= 'Missing code-excerpt management for code block';
    }

    return errorSummary;
  }

  /// Validates that the plugin has a supported platforms table following the
  /// expected format, returning an error string if any issues are found.
  String? _validateSupportedPlatforms(
      List<String> readmeLines, Pubspec pubspec) {
    // Example table following expected format:
    // |                | Android | iOS      | Web                    |
    // |----------------|---------|----------|------------------------|
    // | **Support**    | SDK 21+ | iOS 10+* | [See `camera_web `][1] |
    final int detailsLineNumber = readmeLines
        .indexWhere((String line) => line.startsWith('| **Support**'));
    if (detailsLineNumber == -1) {
      return 'No OS support table found';
    }
    final int osLineNumber = detailsLineNumber - 2;
    if (osLineNumber < 0 || !readmeLines[osLineNumber].startsWith('|')) {
      return 'OS support table does not have the expected header format';
    }

    // Utility method to convert an iterable of strings to a case-insensitive
    // sorted, comma-separated string of its elements.
    String sortedListString(Iterable<String> entries) {
      final List<String> entryList = entries.toList();
      entryList.sort(
          (String a, String b) => a.toLowerCase().compareTo(b.toLowerCase()));
      return entryList.join(', ');
    }

    // Validate that the supported OS lists match.
    final dynamic platformsEntry = pubspec.flutter!['plugin']!['platforms'];
    if (platformsEntry == null) {
      logWarning('Plugin not support any platforms');
      return null;
    }
    final YamlMap platformSupportMaps = platformsEntry as YamlMap;
    final Set<String> actuallySupportedPlatform =
        platformSupportMaps.keys.toSet().cast<String>();
    final Iterable<String> documentedPlatforms = readmeLines[osLineNumber]
        .split('|')
        .map((String entry) => entry.trim())
        .where((String entry) => entry.isNotEmpty);
    final Set<String> documentedPlatformsLowercase =
        documentedPlatforms.map((String entry) => entry.toLowerCase()).toSet();
    if (actuallySupportedPlatform.length != documentedPlatforms.length ||
        actuallySupportedPlatform
                .intersection(documentedPlatformsLowercase)
                .length !=
            actuallySupportedPlatform.length) {
      printError('''
${indentation}OS support table does not match supported platforms:
${indentation * 2}Actual:     ${sortedListString(actuallySupportedPlatform)}
${indentation * 2}Documented: ${sortedListString(documentedPlatformsLowercase)}
''');
      return 'Incorrect OS support table';
    }

    // Enforce a standard set of capitalizations for the OS headings.
    final Iterable<String> incorrectCapitalizations = documentedPlatforms
        .toSet()
        .difference(_standardPlatformNames.values.toSet());
    if (incorrectCapitalizations.isNotEmpty) {
      final Iterable<String> expectedVersions = incorrectCapitalizations
          .map((String name) => _standardPlatformNames[name.toLowerCase()]!);
      printError('''
${indentation}Incorrect OS capitalization: ${sortedListString(incorrectCapitalizations)}
${indentation * 2}Please use standard capitalizations: ${sortedListString(expectedVersions)}
''');
      return 'Incorrect OS support formatting';
    }

    // TODO(stuartmorgan): Add validation that the minimums in the table are
    // consistent with what the current implementations require. See
    // https://github.com/flutter/flutter/issues/84200
    return null;
  }

  /// Returns true if the README still has the boilerplate from the
  /// `flutter create` templates.
  bool _containsTemplateBoilerplate(List<String> readmeLines) {
    return readmeLines.any((String line) =>
        line.contains('For help getting started with Flutter'));
  }
}
