// 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;
  final 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.', () {
      const String authorAssociation = 'MEMBER';
      assert(revert.isValidAuthor('octocat', authorAssociation));
    });

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

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

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

  group('Pattern matching for revert text link', () {
    test('Link extraction from description is successful.', () {
      // input, expected
      final 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) {
        final String? linkFound = revert.extractLinkFromText(key);
        assert(linkFound != null);
        assert(linkFound == value);
      });
    });

    test('Link extraction from description returns null', () {
      final 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) {
        final String? linkFound = revert.extractLinkFromText(key);
        assert(linkFound == null);
      });
    });
  });

  group('Validate Pull Requests.', () {
    test('Validation fails on author validation, returns error.', () async {
      final Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      final 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);
      final 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 {
      final Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      final 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);
      final 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 {
      final Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      final 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);
      final 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 {
      final Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      final github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);

      final Map<String, dynamic> originalPullRequestJsonMap =
          jsonDecode(originalPullRequestJson) as Map<String, dynamic>;
      final 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,
        ),
      );
      final 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 {
      final Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      final github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);

      final Map<String, dynamic> originalPullRequestJsonMap =
          jsonDecode(originalPullRequestJson) as Map<String, dynamic>;
      final 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;

      final 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 {
      final Map<String, dynamic> pullRequestJsonMap = jsonDecode(revertPullRequestJson) as Map<String, dynamic>;
      final github.PullRequest revertPullRequest = github.PullRequest.fromJson(pullRequestJsonMap);
      final Map<String, dynamic> queryResultJsonDecode =
          jsonDecode(queryResultRepositoryOwnerJson) as Map<String, dynamic>;
      final QueryResult queryResult = QueryResult.fromJson(queryResultJsonDecode);

      final Map<String, dynamic> originalPullRequestJsonMap =
          jsonDecode(originalPullRequestJson) as Map<String, dynamic>;
      final 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;

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