// Copyright 2019 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 'dart:async';

import 'package:appengine/appengine.dart';
import 'package:cocoon_service/src/request_handling/exceptions.dart';
import 'package:graphql/client.dart';
import 'package:meta/meta.dart';

import '../datastore/cocoon_config.dart';
import '../foundation/providers.dart';
import '../foundation/typedefs.dart';
import '../request_handling/api_request_handler.dart';
import '../request_handling/authentication.dart';
import '../request_handling/body.dart';

import 'check_for_waiting_pull_requests_queries.dart';
import 'refresh_cirrus_status.dart';

/// Maximum number of pull requests to merge on each check.
/// This should be kept reasonably low to avoid flooding infra when the tree
/// goes green.
const int _kMergeCountPerCycle = 2;

@immutable
class CheckForWaitingPullRequests extends ApiRequestHandler<Body> {
  const CheckForWaitingPullRequests(
    Config config,
    AuthenticationProvider authenticationProvider, {
    @visibleForTesting LoggingProvider loggingProvider,
  })  : loggingProvider = loggingProvider ?? Providers.serviceScopeLogger,
        super(config: config, authenticationProvider: authenticationProvider);

  final LoggingProvider loggingProvider;

  @override
  Future<Body> get() async {
    final Logging log = loggingProvider();
    final GraphQLClient client = await config.createGitHubGraphQLClient();

    await _checkPRs('flutter', 'flutter', log, client);
    await _checkPRs('flutter', 'engine', log, client);

    return Body.empty;
  }

  Future<void> _checkPRs(
    String owner,
    String name,
    Logging log,
    GraphQLClient client,
  ) async {
    int mergeCount = 0;
    final Map<String, dynamic> data = await _queryGraphQL(
      owner,
      name,
      log,
      client,
    );
    for (_AutoMergeQueryResult queryResult
        in await _parseQueryData(data, name)) {
      if (mergeCount < _kMergeCountPerCycle && queryResult.shouldMerge) {
        final bool merged = await _mergePullRequest(
          queryResult.graphQLId,
          queryResult.sha,
          log,
          client,
        );
        if (merged) {
          mergeCount++;
        }
      } else if (queryResult.shouldRemoveLabel) {
        await _removeLabel(
          queryResult.graphQLId,
          queryResult.removalMessage,
          queryResult.labelId,
          client,
        );
      }
    }
  }

  Future<Map<String, dynamic>> _queryGraphQL(
    String owner,
    String name,
    Logging log,
    GraphQLClient client,
  ) async {
    final String labelName = config.waitingForTreeToGoGreenLabelName;

    final QueryResult result = await client.query(
      QueryOptions(
        document: labeledPullRequestsWithReviewsQuery,
        fetchPolicy: FetchPolicy.noCache,
        variables: <String, dynamic>{
          'sOwner': owner,
          'sName': name,
          'sLabelName': labelName,
        },
      ),
    );

    if (result.hasErrors) {
      for (GraphQLError error in result.errors) {
        log.error(error.toString());
      }
      throw const BadRequestException('GraphQL query failed');
    }

    return result.data as Map<String, dynamic>;
  }

  Future<bool> _removeLabel(
    String id,
    String message,
    String labelId,
    GraphQLClient client,
  ) async {
    final QueryResult result = await client.mutate(MutationOptions(
      document: removeLabelMutation,
      variables: <String, dynamic>{
        'id': id,
        'sBody': message,
        'labelId': labelId,
      },
    ));
    if (result.hasErrors) {
      for (GraphQLError error in result.errors) {
        log.error(error.toString());
      }
      return false;
    }
    return true;
  }

  Future<bool> _mergePullRequest(
    String id,
    String sha,
    Logging log,
    GraphQLClient client,
  ) async {
    final QueryResult result = await client.mutate(MutationOptions(
      document: mergePullRequestMutation,
      variables: <String, dynamic>{
        'id': id,
        'oid': sha,
      },
    ));

    if (result.hasErrors) {
      for (GraphQLError error in result.errors) {
        log.error(error.toString());
      }
      return false;
    }
    return true;
  }

  /// Parses a GraphQL query to a list of [_AutoMergeQueryResult]s.
  ///
  /// This method will not return null, but may return an empty list.
  Future<List<_AutoMergeQueryResult>> _parseQueryData(
      Map<String, dynamic> data, String name) async {
    final Map<String, dynamic> repository =
        data['repository'] as Map<String, dynamic>;
    if (repository == null || repository.isEmpty) {
      throw StateError('Query did not return a repository.');
    }

    final Map<String, dynamic> label =
        repository['labels']['nodes'].single as Map<String, dynamic>;
    if (label == null || label.isEmpty) {
      throw StateError(
          'Query did not find information about the waitingForTreeToGoGreen label.');
    }
    final String labelId = label['id'] as String;
    final List<_AutoMergeQueryResult> list = <_AutoMergeQueryResult>[];
    final Iterable<Map<String, dynamic>> pullRequests =
        (label['pullRequests']['nodes'] as List<dynamic>)
            .cast<Map<String, dynamic>>();
    for (Map<String, dynamic> pullRequest in pullRequests) {
      final Map<String, dynamic> commit = pullRequest['commits']['nodes']
          .single['commit'] as Map<String, dynamic>;
      // Skip commits that are less than an hour old.
      // Use the committedDate if pushedDate is null (commitedDate cannot be null).
      final DateTime utcDate = DateTime.parse(commit['pushedDate'] as String ??
              commit['committedDate'] as String)
          .toUtc();
      if (utcDate
          .add(const Duration(hours: 1))
          .isAfter(DateTime.now().toUtc())) {
        continue;
      }
      final String author = pullRequest['author']['login'] as String;
      final String id = pullRequest['id'] as String;
      final int number = pullRequest['number'] as int;

      final Set<String> changeRequestAuthors = <String>{};
      final bool hasApproval = config.rollerAccounts.contains(author) ||
          _checkApproval(
            (pullRequest['reviews']['nodes'] as List<dynamic>)
                .cast<Map<String, dynamic>>(),
            changeRequestAuthors,
          );

      final String sha = commit['oid'] as String;
      final List<Map<String, dynamic>> statuses =
          (commit['status']['contexts'] as List<dynamic>)
              .cast<Map<String, dynamic>>();
      final Set<String> failingStatuses = <String>{};

      final bool ciSuccessful = await _checkStatuses(
        sha,
        failingStatuses,
        statuses,
        name,
        'pull/$number',
      );

      list.add(_AutoMergeQueryResult(
        graphQLId: id,
        ciSuccessful: ciSuccessful,
        failingStatuses: failingStatuses,
        hasApprovedReview: hasApproval,
        changeRequestAuthors: changeRequestAuthors,
        number: number,
        sha: sha,
        labelId: labelId,
      ));
    }
    return list;
  }

  /// Returns whether all statuses are successful.
  ///
  /// Also fills [failures] with the names of any status/check that has failed.
  Future<bool> _checkStatuses(
    String sha,
    Set<String> failures,
    List<Map<String, dynamic>> statuses,
    String name,
    String branch,
  ) async {
    assert(failures != null && failures.isEmpty);
    bool allSuccess = true;

    // The status checks that are not related to changes in this PR.
    const Set<String> notInAuthorsControl = <String>{
      'flutter-build', // flutter repo
      'luci-engine', // engine repo
    };

    for (Map<String, dynamic> status in statuses) {
      final String name = status['context'] as String;
      if (status['state'] != 'SUCCESS') {
        allSuccess = false;
        if (status['state'] == 'FAILURE' &&
            !notInAuthorsControl.contains(name)) {
          failures.add(name);
        }
      }
    }

    const List<String> _failedStates = <String>['FAILED', 'ABORTED'];
    const List<String> _succeededStates = <String>['COMPLETED', 'SKIPPED'];
    final GraphQLClient cirrusClient = await config.createCirrusGraphQLClient();
    final List<CirrusResult> cirrusResults =
        await queryCirrusGraphQL(sha, cirrusClient, log, name);
    if (!cirrusResults
        .any((CirrusResult cirrusResult) => cirrusResult.branch == branch)) {
      return allSuccess;
    }
    final List<Map<String, dynamic>> cirrusStatuses = cirrusResults
        .firstWhere(
            (CirrusResult cirrusResult) => cirrusResult.branch == branch)
        .tasks;
    if (cirrusStatuses == null) {
      return allSuccess;
    }
    for (Map<String, dynamic> runStatus in cirrusStatuses) {
      final String status = runStatus['status'] as String;
      final String name = runStatus['name'] as String;
      if (!_succeededStates.contains(status)) {
        allSuccess = false;
      }
      if (_failedStates.contains(status)) {
        failures.add(name);
      }
    }
    return allSuccess;
  }
}

/// Parses the graphQL response reviews.
///
/// Checks that the authorAssociation is of a MEMBER or OWNER (ignore reviews
/// from people who don't have write access to the repo).
///
/// If there are any CHANGES_REQUESTED reviews, checks if the same author has
/// subsequently APPROVED.  From testing, dismissing a review means it won't
/// show up in this list since it will have a status of DISMISSED and we only
/// ask for CHANGES_REQUESTED or APPROVED - however, adding a new review does
/// not automatically dismiss the previous one (why, GitHub? Why?).
///
/// If the author has not subsequently approved or dismissed the review, the
/// name will be added to the changeRequestAuthors set.
///
/// Returns false if no approved reviews or any oustanding change request
/// reviews.
///
/// Returns true if at least one approved review and no outstanding change
/// request reviews.
bool _checkApproval(
  List<Map<String, dynamic>> reviewNodes,
  Set<String> changeRequestAuthors,
) {
  assert(changeRequestAuthors != null && changeRequestAuthors.isEmpty);
  bool hasAtLeastOneApprove = false;
  for (Map<String, dynamic> review in reviewNodes) {
    // Ignore reviews from non-members/owners.
    if (review['authorAssociation'] != 'MEMBER' &&
        review['authorAssociation'] != 'OWNER') {
      continue;
    }

    // Reviews come back in order of creation.
    final String state = review['state'] as String;
    final String authorLogin = review['author']['login'] as String;
    if (state == 'APPROVED') {
      hasAtLeastOneApprove = true;
      changeRequestAuthors.remove(authorLogin);
    } else if (state == 'CHANGES_REQUESTED') {
      changeRequestAuthors.add(authorLogin);
    }
  }

  return hasAtLeastOneApprove && changeRequestAuthors.isEmpty;
}

/// A model class describing the state of a pull request that has the "waiting
/// for tree to go green" label on it.
@immutable
class _AutoMergeQueryResult {
  const _AutoMergeQueryResult({
    @required this.graphQLId,
    @required this.hasApprovedReview,
    @required this.changeRequestAuthors,
    @required this.ciSuccessful,
    @required this.failingStatuses,
    @required this.number,
    @required this.sha,
    @required this.labelId,
  })  : assert(graphQLId != null),
        assert(hasApprovedReview != null),
        assert(changeRequestAuthors != null),
        assert(ciSuccessful != null),
        assert(failingStatuses != null),
        assert(number != null),
        assert(sha != null),
        assert(labelId != null);

  /// The GitHub GraphQL ID of this pull request.
  final String graphQLId;

  /// Whether the pull request has at least one approved review.
  final bool hasApprovedReview;

  /// A set of login names that have at least one outstanding change request.
  final Set<String> changeRequestAuthors;

  /// Whether CI has run successfully on the pull request.
  final bool ciSuccessful;

  /// A set of status names that have failed.
  final Set<String> failingStatuses;

  /// The pull request number.
  final int number;

  /// The git SHA to be merged.
  final String sha;

  /// The GitHub GraphQL ID of the waiting label.
  final String labelId;

  /// Whether it is sane to automatically merge this PR.
  bool get shouldMerge =>
      ciSuccessful &&
      failingStatuses.isEmpty &&
      hasApprovedReview &&
      changeRequestAuthors.isEmpty;

  /// Whether the auto-merge label should be removed from this PR.
  bool get shouldRemoveLabel =>
      !hasApprovedReview ||
      changeRequestAuthors.isNotEmpty ||
      failingStatuses.isNotEmpty;

  /// An appropriate message to leave when removing the label.
  String get removalMessage {
    if (!shouldRemoveLabel) {
      return '';
    }
    final StringBuffer buffer = StringBuffer();
    buffer.writeln(
        'This pull request is not suitable for automatic merging in its '
        'current state.');
    buffer.writeln();
    if (!hasApprovedReview && changeRequestAuthors.isEmpty) {
      buffer.writeln(
          '- Please get at least one approved review before re-applying this '
          'label. __Reviewers__: If you left a comment approving, please use '
          'the "approve" review action instead.');
    }
    for (String author in changeRequestAuthors) {
      buffer.writeln(
          '- This pull request has changes requested by @$author. Please '
          'resolve those before re-applying the label.');
    }
    for (String status in failingStatuses) {
      buffer.writeln(
          '- The status or check suite $status has failed. Please fix the '
          'issues identified (or deflake) before re-applying this label.');
    }
    return buffer.toString();
  }

  @override
  String toString() {
    return '$runtimeType{PR#$number, '
        'id: $graphQLId, '
        'sha: $sha, '
        'ciSuccessful: $ciSuccessful, '
        'hasApprovedReview: $hasApprovedReview, '
        'changeRequestAuthors: $changeRequestAuthors, '
        'labelId: $labelId, '
        'shouldMerge: $shouldMerge}';
  }
}
