// Copyright 2022 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:auto_submit/model/auto_submit_query_result.dart' as auto;
import 'package:auto_submit/service/github_service.dart';
import 'package:auto_submit/validations/validation.dart';
import 'package:github/github.dart' as github;

import '../service/log.dart';

class Revert extends Validation {
  Revert({
    required super.config,
  });

  static const Set<String> allowedReviewers = <String>{ORG_MEMBER, ORG_OWNER};

  @override
  Future<ValidationResult> validate(auto.QueryResult result, github.PullRequest messagePullRequest) async {
    final auto.PullRequest pullRequest = result.repository!.pullRequest!;
    final String authorAssociation = pullRequest.authorAssociation!;
    final String? author = pullRequest.author!.login;

    if (!isValidAuthor(author, authorAssociation)) {
      String message = 'The author $author does not have permissions to make this request.';
      log.info(message);
      return ValidationResult(false, Action.REMOVE_LABEL, message);
    }

    bool? canMerge = messagePullRequest.mergeable;
    if (canMerge == null || !canMerge) {
      String message =
          'This pull request cannot be merged due to conflicts. Please resolve conflicts and re-add the revert label.';
      log.info(message);
      return ValidationResult(false, Action.REMOVE_LABEL, message);
    }

    String? pullRequestBody = messagePullRequest.body;
    String? revertLink = extractLinkFromText(pullRequestBody);
    if (revertLink == null) {
      String message =
          'A reverts link could not be found or was formatted incorrectly. Format is \'Reverts owner/repo#id\'';
      log.info(message);
      return ValidationResult(false, Action.REMOVE_LABEL, message);
    }

    github.RepositorySlug repositorySlug = _getSlugFromLink(revertLink);
    GithubService githubService = await config.createGithubService(repositorySlug);
    int pullRequestId = _getPullRequestNumberFromLink(revertLink);
    github.PullRequest requestToRevert = await githubService.getPullRequest(repositorySlug, pullRequestId);

    bool requestsMatch = await githubService.comparePullRequests(repositorySlug, requestToRevert, messagePullRequest);

    if (requestsMatch) {
      return ValidationResult(
        true,
        Action.IGNORE_FAILURE,
        'Revert request has been verified and will be queued for merge.',
      );
    }

    return ValidationResult(
      false,
      Action.REMOVE_LABEL,
      'Validation of the revert request has failed. Verify the files in the revert request are the same as the original PR and resubmit the revert request.',
    );
  }

  /// Only a team member and code owner can submit a revert request without a review.
  bool isValidAuthor(String? author, String authorAssociation) {
    return config.rollerAccounts.contains(author) || allowedReviewers.contains(authorAssociation);
  }

  /// The full text here is 'Reverts flutter/cocoon#XXXXX' as output by github
  /// the link must be in the form github.com/flutter/repo/pull/id
  String? extractLinkFromText(String? bodyText) {
    if (bodyText == null) {
      return null;
    }
    final RegExp regExp = RegExp(r'^[Rr]everts[\s]+([-\.a-zA-Z_]+/[-\.a-zA-Z_]+#[0-9]+)$', multiLine: true);
    Iterable<RegExpMatch> matches = regExp.allMatches(bodyText);
    if (matches.isNotEmpty) {
      return matches.elementAt(0).group(1);
    }
    return null;
  }

  /// Split a reverts link on the '#' then the '/' to get the parts of the repo
  /// slug. It is assumed that the link has the format flutter/repo#id.
  github.RepositorySlug _getSlugFromLink(String link) {
    List<String> linkSplit = link.split('#');
    List<String> slugSplit = linkSplit.elementAt(0).split('/');
    return github.RepositorySlug(slugSplit.elementAt(0), slugSplit.elementAt(1));
  }

  /// Split a reverts link on the '#' to get the id part of the link.
  /// It is assumed that the link has the format flutter/repo#id.
  int _getPullRequestNumberFromLink(String link) {
    List<String> linkSplit = link.split('#');
    return int.parse(linkSplit.elementAt(1));
  }
}
