// 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:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';

import 'common/core.dart';
import 'common/git_version_finder.dart';
import 'common/package_looping_command.dart';
import 'common/package_state_utils.dart';
import 'common/process_runner.dart';
import 'common/pub_version_finder.dart';
import 'common/repository_package.dart';

/// Categories of version change types.
enum NextVersionType {
  /// A breaking change.
  BREAKING_MAJOR,

  /// A minor change (e.g., added feature).
  MINOR,

  /// A bugfix change.
  PATCH,

  /// The release of an existing pre-1.0 version.
  V1_RELEASE,
}

/// The state of a package's version relative to the comparison base.
enum _CurrentVersionState {
  /// The version is unchanged.
  unchanged,

  /// The version has increased, and the transition is valid.
  validIncrease,

  /// The version has decrease, and the transition is a valid revert.
  validRevert,

  /// The version has changed, and the transition is invalid.
  invalidChange,

  /// The package is new.
  newPackage,

  /// There was an error determining the version state.
  unknown,
}

/// Returns the set of allowed next non-prerelease versions, with their change
/// type, for [version].
///
/// [newVersion] is used to check whether this is a pre-1.0 version bump, as
/// those have different semver rules.
@visibleForTesting
Map<Version, NextVersionType> getAllowedNextVersions(
  Version version, {
  required Version newVersion,
}) {
  final Map<Version, NextVersionType> allowedNextVersions =
      <Version, NextVersionType>{
    version.nextMajor: NextVersionType.BREAKING_MAJOR,
    version.nextMinor: NextVersionType.MINOR,
    version.nextPatch: NextVersionType.PATCH,
  };

  if (version.major < 1 && newVersion.major < 1) {
    int nextBuildNumber = -1;
    if (version.build.isEmpty) {
      nextBuildNumber = 1;
    } else {
      final int currentBuildNumber = version.build.first as int;
      nextBuildNumber = currentBuildNumber + 1;
    }
    final Version nextBuildVersion = Version(
      version.major,
      version.minor,
      version.patch,
      build: nextBuildNumber.toString(),
    );
    allowedNextVersions.clear();
    allowedNextVersions[version.nextMajor] = NextVersionType.V1_RELEASE;
    allowedNextVersions[version.nextMinor] = NextVersionType.BREAKING_MAJOR;
    allowedNextVersions[version.nextPatch] = NextVersionType.MINOR;
    allowedNextVersions[nextBuildVersion] = NextVersionType.PATCH;
  }
  return allowedNextVersions;
}

/// A command to validate version changes to packages.
class VersionCheckCommand extends PackageLoopingCommand {
  /// Creates an instance of the version check command.
  VersionCheckCommand(
    Directory packagesDir, {
    ProcessRunner processRunner = const ProcessRunner(),
    Platform platform = const LocalPlatform(),
    GitDir? gitDir,
    http.Client? httpClient,
  })  : _pubVersionFinder =
            PubVersionFinder(httpClient: httpClient ?? http.Client()),
        super(
          packagesDir,
          processRunner: processRunner,
          platform: platform,
          gitDir: gitDir,
        ) {
    argParser.addFlag(
      _againstPubFlag,
      help: 'Whether the version check should run against the version on pub.\n'
          'Defaults to false, which means the version check only run against '
          'the previous version in code.',
    );
    argParser.addOption(_prLabelsArg,
        help: 'A comma-separated list of labels associated with this PR, '
            'if applicable.\n\n'
            'If supplied, this may be to allow overrides to some version '
            'checks.');
    argParser.addFlag(_checkForMissingChanges,
        help: 'Validates that changes to packages include CHANGELOG and '
            'version changes unless they meet an established exemption.\n\n'
            'If used with --$_prLabelsArg, this is should only be '
            'used in pre-submit CI checks, to  prevent post-submit breakage '
            'when labels are no longer applicable.',
        hide: true);
    argParser.addFlag(_ignorePlatformInterfaceBreaks,
        help: 'Bypasses the check that platform interfaces do not contain '
            'breaking changes.\n\n'
            'This is only intended for use in post-submit CI checks, to '
            'prevent post-submit breakage when overriding the check with '
            'labels. Pre-submit checks should always use '
            '--$_prLabelsArg instead.',
        hide: true);
  }

  static const String _againstPubFlag = 'against-pub';
  static const String _prLabelsArg = 'pr-labels';
  static const String _checkForMissingChanges = 'check-for-missing-changes';
  static const String _ignorePlatformInterfaceBreaks =
      'ignore-platform-interface-breaks';

  /// The label that must be on a PR to allow a breaking
  /// change to a platform interface.
  static const String _breakingChangeOverrideLabel =
      'override: allow breaking change';

  /// The label that must be on a PR to allow skipping a version change for a PR
  /// that would normally require one.
  static const String _missingVersionChangeOverrideLabel =
      'override: no versioning needed';

  /// The label that must be on a PR to allow skipping a CHANGELOG change for a
  /// PR that would normally require one.
  static const String _missingChangelogChangeOverrideLabel =
      'override: no changelog needed';

  final PubVersionFinder _pubVersionFinder;

  late final GitVersionFinder _gitVersionFinder;
  late final String _mergeBase;
  late final List<String> _changedFiles;

  late final Set<String> _prLabels = _getPRLabels();

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

  @override
  final String description =
      'Checks if the versions of packages have been incremented per pub specification.\n'
      'Also checks if the latest version in CHANGELOG matches the version in pubspec.\n\n'
      'This command requires "pub" and "flutter" to be in your path.';

  @override
  bool get hasLongOutput => false;

  @override
  Future<void> initializeRun() async {
    _gitVersionFinder = await retrieveVersionFinder();
    _mergeBase = await _gitVersionFinder.getBaseSha();
    _changedFiles = await _gitVersionFinder.getChangedFiles();
  }

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    final Pubspec? pubspec = _tryParsePubspec(package);
    if (pubspec == null) {
      // No remaining checks make sense, so fail immediately.
      return PackageResult.fail(<String>['Invalid pubspec.yaml.']);
    }

    if (pubspec.publishTo == 'none') {
      return PackageResult.skip('Found "publish_to: none".');
    }

    final Version? currentPubspecVersion = pubspec.version;
    if (currentPubspecVersion == null) {
      printError('${indentation}No version found in pubspec.yaml. A package '
          'that intentionally has no version should be marked '
          '"publish_to: none".');
      // No remaining checks make sense, so fail immediately.
      return PackageResult.fail(<String>['No pubspec.yaml version.']);
    }

    final List<String> errors = <String>[];

    bool versionChanged;
    final _CurrentVersionState versionState =
        await _getVersionState(package, pubspec: pubspec);
    switch (versionState) {
      case _CurrentVersionState.unchanged:
        versionChanged = false;
        break;
      case _CurrentVersionState.validIncrease:
      case _CurrentVersionState.validRevert:
      case _CurrentVersionState.newPackage:
        versionChanged = true;
        break;
      case _CurrentVersionState.invalidChange:
        versionChanged = true;
        errors.add('Disallowed version change.');
        break;
      case _CurrentVersionState.unknown:
        versionChanged = false;
        errors.add('Unable to determine previous version.');
        break;
    }

    if (!(await _validateChangelogVersion(package,
        pubspec: pubspec, pubspecVersionState: versionState))) {
      errors.add('CHANGELOG.md failed validation.');
    }

    // If there are no other issues, make sure that there isn't a missing
    // change to the version and/or CHANGELOG.
    if (getBoolArg(_checkForMissingChanges) &&
        !versionChanged &&
        errors.isEmpty) {
      final String? error = await _checkForMissingChangeError(package);
      if (error != null) {
        errors.add(error);
      }
    }

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

  @override
  Future<void> completeRun() async {
    _pubVersionFinder.httpClient.close();
  }

  /// Returns the previous published version of [package].
  ///
  /// [packageName] must be the actual name of the package as published (i.e.,
  /// the name from pubspec.yaml, not the on disk name if different.)
  Future<Version?> _fetchPreviousVersionFromPub(String packageName) async {
    final PubVersionFinderResponse pubVersionFinderResponse =
        await _pubVersionFinder.getPackageVersion(packageName: packageName);
    switch (pubVersionFinderResponse.result) {
      case PubVersionFinderResult.success:
        return pubVersionFinderResponse.versions.first;
      case PubVersionFinderResult.fail:
        printError('''
${indentation}Error fetching version on pub for $packageName.
${indentation}HTTP Status ${pubVersionFinderResponse.httpResponse.statusCode}
${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body}
''');
        return null;
      case PubVersionFinderResult.noPackageFound:
        return Version.none;
    }
  }

  /// Returns the version of [package] from git at the base comparison hash.
  Future<Version?> _getPreviousVersionFromGit(RepositoryPackage package) async {
    final File pubspecFile = package.pubspecFile;
    final String relativePath =
        path.relative(pubspecFile.absolute.path, from: (await gitDir).path);
    // Use Posix-style paths for git.
    final String gitPath = path.style == p.Style.windows
        ? p.posix.joinAll(path.split(relativePath))
        : relativePath;
    return _gitVersionFinder.getPackageVersion(gitPath, gitRef: _mergeBase);
  }

  /// Returns the state of the verison of [package] relative to the comparison
  /// base (git or pub, depending on flags).
  Future<_CurrentVersionState> _getVersionState(
    RepositoryPackage package, {
    required Pubspec pubspec,
  }) async {
    // This method isn't called unless `version` is non-null.
    final Version currentVersion = pubspec.version!;
    Version? previousVersion;
    String previousVersionSource;
    if (getBoolArg(_againstPubFlag)) {
      previousVersionSource = 'pub';
      previousVersion = await _fetchPreviousVersionFromPub(pubspec.name);
      if (previousVersion == null) {
        return _CurrentVersionState.unknown;
      }
      if (previousVersion != Version.none) {
        print(
            '$indentation${pubspec.name}: Current largest version on pub: $previousVersion');
      }
    } else {
      previousVersionSource = _mergeBase;
      previousVersion =
          await _getPreviousVersionFromGit(package) ?? Version.none;
    }
    if (previousVersion == Version.none) {
      print('${indentation}Unable to find previous version '
          '${getBoolArg(_againstPubFlag) ? 'on pub server' : 'at git base'}.');
      logWarning(
          '${indentation}If this package is not new, something has gone wrong.');
      return _CurrentVersionState.newPackage;
    }

    if (previousVersion == currentVersion) {
      print('${indentation}No version change.');
      return _CurrentVersionState.unchanged;
    }

    // Check for reverts when doing local validation.
    if (!getBoolArg(_againstPubFlag) && currentVersion < previousVersion) {
      // Since this skips validation, try to ensure that it really is likely
      // to be a revert rather than a typo by checking that the transition
      // from the lower version to the new version would have been valid.
      if (_shouldAllowVersionChange(
          oldVersion: currentVersion, newVersion: previousVersion)) {
        logWarning('${indentation}New version is lower than previous version. '
            'This is assumed to be a revert.');
        return _CurrentVersionState.validRevert;
      }
    }

    final Map<Version, NextVersionType> allowedNextVersions =
        getAllowedNextVersions(previousVersion, newVersion: currentVersion);

    if (_shouldAllowVersionChange(
        oldVersion: previousVersion, newVersion: currentVersion)) {
      print('$indentation$previousVersion -> $currentVersion');
    } else {
      printError('${indentation}Incorrectly updated version.\n'
          '${indentation}HEAD: $currentVersion, $previousVersionSource: $previousVersion.\n'
          '${indentation}Allowed versions: $allowedNextVersions');
      return _CurrentVersionState.invalidChange;
    }

    // Check whether the version (or for a pre-release, the version that
    // pre-release would eventually be released as) is a breaking change, and
    // if so, validate it.
    final Version targetReleaseVersion =
        currentVersion.isPreRelease ? currentVersion.nextPatch : currentVersion;
    if (allowedNextVersions[targetReleaseVersion] ==
            NextVersionType.BREAKING_MAJOR &&
        !_validateBreakingChange(package)) {
      printError('${indentation}Breaking change detected.\n'
          '${indentation}Breaking changes to platform interfaces are not '
          'allowed without explicit justification.\n'
          '${indentation}See '
          'https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages '
          'for more information.');
      return _CurrentVersionState.invalidChange;
    }

    return _CurrentVersionState.validIncrease;
  }

  /// Checks whether or not [package]'s CHANGELOG's versioning is correct,
  /// both that it matches [pubspec] and that NEXT is used correctly, printing
  /// the results of its checks.
  ///
  /// Returns false if the CHANGELOG fails validation.
  Future<bool> _validateChangelogVersion(
    RepositoryPackage package, {
    required Pubspec pubspec,
    required _CurrentVersionState pubspecVersionState,
  }) async {
    // This method isn't called unless `version` is non-null.
    final Version fromPubspec = pubspec.version!;

    // get first version from CHANGELOG
    final File changelog = package.changelogFile;
    final List<String> lines = changelog.readAsLinesSync();
    String? firstLineWithText;
    final Iterator<String> iterator = lines.iterator;
    while (iterator.moveNext()) {
      if (iterator.current.trim().isNotEmpty) {
        firstLineWithText = iterator.current.trim();
        break;
      }
    }
    // Remove all leading mark down syntax from the version line.
    String? versionString = firstLineWithText?.split(' ').last;

    final String badNextErrorMessage = '${indentation}When bumping the version '
        'for release, the NEXT section should be incorporated into the new '
        "version's release notes.";

    // Skip validation for the special NEXT version that's used to accumulate
    // changes that don't warrant publishing on their own.
    final bool hasNextSection = versionString == 'NEXT';
    if (hasNextSection) {
      // NEXT should not be present in a commit that increases the version.
      if (pubspecVersionState == _CurrentVersionState.validIncrease ||
          pubspecVersionState == _CurrentVersionState.invalidChange) {
        printError(badNextErrorMessage);
        return false;
      }
      print(
          '${indentation}Found NEXT; validating next version in the CHANGELOG.');
      // Ensure that the version in pubspec hasn't changed without updating
      // CHANGELOG. That means the next version entry in the CHANGELOG should
      // pass the normal validation.
      versionString = null;
      while (iterator.moveNext()) {
        if (iterator.current.trim().startsWith('## ')) {
          versionString = iterator.current.trim().split(' ').last;
          break;
        }
      }
    }

    if (versionString == null) {
      printError('${indentation}Unable to find a version in CHANGELOG.md');
      print('${indentation}The current version should be on a line starting '
          'with "## ", either on the first non-empty line or after a "## NEXT" '
          'section.');
      return false;
    }

    final Version fromChangeLog;
    try {
      fromChangeLog = Version.parse(versionString);
    } on FormatException {
      printError('"$versionString" could not be parsed as a version.');
      return false;
    }

    if (fromPubspec != fromChangeLog) {
      printError('''
${indentation}Versions in CHANGELOG.md and pubspec.yaml do not match.
${indentation}The version in pubspec.yaml is $fromPubspec.
${indentation}The first version listed in CHANGELOG.md is $fromChangeLog.
''');
      return false;
    }

    // If NEXT wasn't the first section, it should not exist at all.
    if (!hasNextSection) {
      final RegExp nextRegex = RegExp(r'^#+\s*NEXT\s*$');
      if (lines.any((String line) => nextRegex.hasMatch(line))) {
        printError(badNextErrorMessage);
        return false;
      }
    }

    return true;
  }

  Pubspec? _tryParsePubspec(RepositoryPackage package) {
    try {
      final Pubspec pubspec = package.parsePubspec();
      return pubspec;
    } on Exception catch (exception) {
      printError('${indentation}Failed to parse `pubspec.yaml`: $exception}');
      return null;
    }
  }

  /// Checks whether the current breaking change to [package] should be allowed,
  /// logging extra information for auditing when allowing unusual cases.
  bool _validateBreakingChange(RepositoryPackage package) {
    // Only platform interfaces have breaking change restrictions.
    if (!package.isPlatformInterface) {
      return true;
    }

    if (getBoolArg(_ignorePlatformInterfaceBreaks)) {
      logWarning(
          '${indentation}Allowing breaking change to ${package.displayName} '
          'due to --$_ignorePlatformInterfaceBreaks');
      return true;
    }

    if (_prLabels.contains(_breakingChangeOverrideLabel)) {
      logWarning(
          '${indentation}Allowing breaking change to ${package.displayName} '
          'due to the "$_breakingChangeOverrideLabel" label.');
      return true;
    }

    return false;
  }

  /// Returns the labels associated with this PR, if any, or an empty set
  /// if that flag is not provided.
  Set<String> _getPRLabels() {
    final String labels = getStringArg(_prLabelsArg);
    if (labels.isEmpty) {
      return <String>{};
    }
    return labels.split(',').map((String label) => label.trim()).toSet();
  }

  /// Returns true if the given version transition should be allowed.
  bool _shouldAllowVersionChange(
      {required Version oldVersion, required Version newVersion}) {
    // Get the non-pre-release next version mapping.
    final Map<Version, NextVersionType> allowedNextVersions =
        getAllowedNextVersions(oldVersion, newVersion: newVersion);

    if (allowedNextVersions.containsKey(newVersion)) {
      return true;
    }
    // Allow a pre-release version of a version that would be a valid
    // transition.
    if (newVersion.isPreRelease) {
      final Version targetReleaseVersion = newVersion.nextPatch;
      if (allowedNextVersions.containsKey(targetReleaseVersion)) {
        return true;
      }
    }
    return false;
  }

  /// Returns an error string if the changes to this package should have
  /// resulted in a version change, or shoud have resulted in a CHANGELOG change
  /// but didn't.
  ///
  /// This should only be called if the version did not change.
  Future<String?> _checkForMissingChangeError(RepositoryPackage package) async {
    // Find the relative path to the current package, as it would appear at the
    // beginning of a path reported by getChangedFiles() (which always uses
    // Posix paths).
    final Directory gitRoot =
        packagesDir.fileSystem.directory((await gitDir).path);
    final String relativePackagePath =
        getRelativePosixPath(package.directory, from: gitRoot);

    final PackageChangeState state = await checkPackageChangeState(package,
        changedPaths: _changedFiles,
        relativePackagePath: relativePackagePath,
        git: await retrieveVersionFinder());

    if (!state.hasChanges) {
      return null;
    }

    if (state.needsVersionChange) {
      if (_prLabels.contains(_missingVersionChangeOverrideLabel)) {
        logWarning('Ignoring lack of version change due to the '
            '"$_missingVersionChangeOverrideLabel" label.');
      } else {
        printError(
            'No version change found, but the change to this package could '
            'not be verified to be exempt from version changes according to '
            'repository policy. If this is a false positive, please comment in '
            'the PR to explain why the PR is exempt, and add (or ask your '
            'reviewer to add) the "$_missingVersionChangeOverrideLabel" '
            'label.');
        return 'Missing version change';
      }
    }

    if (!state.hasChangelogChange && state.needsChangelogChange) {
      if (_prLabels.contains(_missingChangelogChangeOverrideLabel)) {
        logWarning('Ignoring lack of CHANGELOG update due to the '
            '"$_missingChangelogChangeOverrideLabel" label.');
      } else {
        printError(
            'No CHANGELOG change found. If this PR needs an exemption from '
            'the standard policy of listing all changes in the CHANGELOG, '
            'comment in the PR to explain why the PR is exempt, and add (or '
            'ask your reviewer to add) the '
            '"$_missingChangelogChangeOverrideLabel" label. Otherwise, '
            'please add a NEXT entry in the CHANGELOG as described in '
            'the contributing guide.');
        return 'Missing CHANGELOG change';
      }
    }

    return null;
  }
}
