// 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 'dart:convert';

import 'package:auto_submit/model/auto_submit_query_result.dart';
import 'package:auto_submit/validations/validation.dart';
import 'package:github/github.dart' as github;
import 'package:retry/retry.dart';
import 'package:test/test.dart';

import 'revert_test_data.dart';

import 'package:auto_submit/validations/revert.dart';

import '../utilities/mocks.dart';
import '../src/service/fake_config.dart';
import '../src/service/fake_github_service.dart';
import '../src/service/fake_graphql_client.dart';

void main() {
  late FakeConfig config;
  late FakeGithubService githubService;
  late FakeGraphQLClient githubGraphQLClient;
  MockGitHub gitHub = MockGitHub();
  late Revert revert;

  /// Setup objects needed across test groups.
  setUp(() {
    githubService = FakeGithubService();
    githubGraphQLClient = FakeGraphQLClient();
    config = FakeConfig(githubService: githubService, githubGraphQLClient: githubGraphQLClient, githubClient: gitHub);
    revert = Revert(
      config: config,
      retryOptions: const RetryOptions(delayFactor: Duration.zero, maxDelay: Duration.zero, maxAttempts: 1),
    );
  });

  group('Author validation tests.', () {
    test('Validate author association member is valid.', () {
      String authorAssociation = 'MEMBER';
      assert(revert.isValidAuthor('octocat', authorAssociation));
    });

    test('Validate author association owner is valid.', () {
      String authorAssociation = 'OWNER';
      assert(revert.isValidAuthor('octocat', authorAssociation));
    });

    test('Validate author dependabot is valid.', () {
      String author = 'dependabot';
      String authorAssociation = 'NON_MEMBER';
      assert(revert.isValidAuthor(author, authorAssociation));
    });

    test('Validate autoroller account is valid.', () {
      String author = 'engine-flutter-autoroll';
      String authorAssociation = 'CONTRIBUTOR';
      assert(revert.isValidAuthor(author, authorAssociation));
    });
  });

  group('Pattern matching for revert text link', () {
    test('Link extraction from description is successful.', () {
      // input, expected
      Map<String, String> tests = <String, String>{};
      tests['Reverts flutter/cocoon#123456'] = 'flutter/cocoon#123456';
      tests['Reverts    flutter/cocoon#123456'] = 'flutter/cocoon#123456';
      tests['Reverts flutter/flutter-intellij#123456'] = 'flutter/flutter-intellij#123456';
      tests['Reverts flutter/platform_tests#123456'] = 'flutter/platform_tests#123456';
      tests['Reverts flutter/.github#123456'] = 'flutter/.github#123456';
      tests['Reverts flutter/assets-for-api-docs#123456'] = 'flutter/assets-for-api-docs#123456';
      tests['Reverts flutter/flutter.github.io#123456'] = 'flutter/flutter.github.io#123456';
      tests['Reverts flutter/flutter_gallery_assets#123456'] = 'flutter/flutter_gallery_assets#123456';
      tests['reverts flutter/cocoon#12323'] = 'flutter/cocoon#12323';
      tests['reverts flutter/cocoon#223'] = 'flutter/cocoon#223';
      tests["""Reverts flutter/cocoon#123456

      Some other notes in the description a developer might add.
      And another note."""] = 'flutter/cocoon#123456';
      tests['Pull request Reverts flutter/flutter#12334 is happening continuously.'] = 'flutter/flutter#12334';
      tests['Reverts reverts flutter/flutter#9876'] = 'flutter/flutter#9876';
      tests["""Some junk reverts flutter/cocoon#4563 is happening continuously.
      Some other tests in the description that someone might add.
      """] = 'flutter/cocoon#4563';
      tests['This some text to add flavor before reverts flutter/flutter#8888.'] = 'flutter/flutter#8888';

      tests.forEach((key, value) {
        String? linkFound = revert.extractLinkFromText(key);
        assert(linkFound != null);
        assert(linkFound == value);
      });
    });

    test('Link extraction from description returns null', () {
      Map<String, String> tests = <String, String>{};
      tests['Revert flutter/cocoon#123456'] = '';
      tests['revert flutter/cocoon#123456'] = '';
      tests['Reverts flutter/cocoon#'] = '';
      tests['Reverts flutter123'] = '';
      // We should not allow processing of more than one link as this can be cause
      // suspicion of other non revert changes in the pull request.
      tests["""Reverts flutter/flutter#12345
      Reverts flutter/flutter#34543"""] = '';
      tests["""This some text to add flavor before reverts flutter/flutter#8888.
      Also please reverts flutter/flutter#7678.
      And reverts flutter/flutter#8763.
      """] = '';
      tests['This is some text flutter/flutter#456...44'] = '';

      tests.forEach((key, value) {
        String? linkFound = revert.extractLinkFromText(key);
        assert(linkFound == null);
      });
    });
  });

  group('Validate Pull Requests.', () {
    test('Validation fails on author validation, returns error.', () async {
      Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      revertPullRequest.authorAssociation = 'CONTRIBUTOR';
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryContributorJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);
      ValidationResult validationResult = await revert.validate(queryResult, revertPullRequest);
      assert(!validationResult.result);
      assert(validationResult.action == Action.REMOVE_LABEL);
      assert(validationResult.message.contains(RegExp(r'The author.*does not have permissions to make this request.')));
    });

    test('Validation fails on merge conflict flag.', () async {
      Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      revertPullRequest.mergeable = false;
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);
      ValidationResult validationResult = await revert.validate(queryResult, revertPullRequest);
      assert(!validationResult.result);
      assert(validationResult.action == Action.REMOVE_LABEL);
      assert(
        validationResult.message ==
            'This pull request cannot be merged due to conflicts. Please resolve conflicts and re-add the revert label.',
      );
    });

    test('Validation fails on malformed reverts link in the pr body.', () async {
      Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      revertPullRequest.body = 'Reverting flutter/cocoon#1234';
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);
      ValidationResult validationResult = await revert.validate(queryResult, revertPullRequest);
      assert(!validationResult.result);
      assert(validationResult.action == Action.REMOVE_LABEL);
      assert(
        validationResult.message ==
            'A reverts link could not be found or was formatted incorrectly. Format is \'Reverts owner/repo#id\'',
      );
    });

    test('Validation returns on checkRun that has not completed.', () async {
      Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);

      Map<String, dynamic> originalPullRequestJsonMap = jsonDecode(originalPullRequestJson) as Map<String, dynamic>;
      github.PullRequest originalPullRequest = github.PullRequest.fromJson(originalPullRequestJsonMap);
      githubService.pullRequestData = originalPullRequest;

      // code gets the original file list then the current file list.
      githubService.usePullRequestFilesList = true;
      githubService.pullRequestFilesMockList.add(originalPullRequestFilesJson);
      githubService.pullRequestFilesMockList.add(revertPullRequestFilesJson);

      // Need to set the mock checkRuns for required CheckRun validation
      githubService.checkRunsData = ciyamlCheckRunNotComplete;

      revert = Revert(
        config: config,
        retryOptions: const RetryOptions(
          delayFactor: Duration.zero,
          maxDelay: Duration.zero,
          maxAttempts: 1,
        ),
      );
      ValidationResult validationResult = await revert.validate(queryResult, revertPullRequest);

      expect(validationResult.result, isFalse);
      expect(validationResult.action, Action.IGNORE_TEMPORARILY);
      expect(validationResult.message, 'Some of the required checks did not complete in time.');
    });

    test('Validation fails on pull request file lists not matching.', () async {
      Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);

      Map<String, dynamic> originalPullRequestJsonMap = jsonDecode(originalPullRequestJson) as Map<String, dynamic>;
      github.PullRequest originalPullRequest = github.PullRequest.fromJson(originalPullRequestJsonMap);
      githubService.pullRequestData = originalPullRequest;

      // code gets the original file list then the current file list.
      githubService.usePullRequestFilesList = true;
      githubService.pullRequestFilesMockList.add(originalPullRequestFilesSubsetJson);
      githubService.pullRequestFilesMockList.add(revertPullRequestFilesJson);

      // Need to set the mock checkRuns for required CheckRun validation
      githubService.checkRunsData = ciyamlCheckRun;

      ValidationResult validationResult = await revert.validate(queryResult, revertPullRequest);
      assert(!validationResult.result);
      assert(validationResult.action == Action.REMOVE_LABEL);
      assert(
        validationResult.message ==
            '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.',
      );
    });

    test('Validation is successful.', () async {
      Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);

      Map<String, dynamic> originalPullRequestJsonMap = jsonDecode(originalPullRequestJson) as Map<String, dynamic>;
      github.PullRequest originalPullRequest = github.PullRequest.fromJson(originalPullRequestJsonMap);
      githubService.pullRequestData = originalPullRequest;

      // code gets the original file list then the current file list.
      githubService.usePullRequestFilesList = true;
      githubService.pullRequestFilesMockList.add(originalPullRequestFilesJson);
      githubService.pullRequestFilesMockList.add(revertPullRequestFilesJson);

      // Need to set the mock checkRuns for required CheckRun validation
      githubService.checkRunsData = ciyamlCheckRun;

      ValidationResult validationResult = await revert.validate(queryResult, revertPullRequest);
      assert(validationResult.result);
      assert(validationResult.message == 'Revert request has been verified and will be queued for merge.');
    });
  });
}
