// Copyright 2021 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:cocoon_service/src/foundation/utils.dart';
import 'package:cocoon_service/src/model/appengine/commit.dart';
import 'package:cocoon_service/src/model/appengine/stage.dart';
import 'package:cocoon_service/src/model/appengine/task.dart';
import 'package:cocoon_service/src/model/ci_yaml/target.dart';
import 'package:cocoon_service/src/model/github/checks.dart' as cocoon_checks;
import 'package:cocoon_service/src/model/luci/buildbucket.dart';
import 'package:cocoon_service/src/service/build_status_provider.dart';
import 'package:cocoon_service/src/service/cache_service.dart';
import 'package:cocoon_service/src/service/config.dart';
import 'package:cocoon_service/src/service/datastore.dart';
import 'package:cocoon_service/src/service/github_checks_service.dart';
import 'package:cocoon_service/src/service/scheduler.dart';
import 'package:gcloud/db.dart' as gcloud_db;
import 'package:gcloud/db.dart';
import 'package:github/github.dart';
import 'package:github/hooks.dart';
import 'package:googleapis/bigquery/v2.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../model/github/checks_test_data.dart';
import '../src/datastore/fake_config.dart';
import '../src/datastore/fake_datastore.dart';
import '../src/service/fake_build_status_provider.dart';
import '../src/request_handling/fake_pubsub.dart';
import '../src/service/fake_buildbucket.dart';
import '../src/service/fake_gerrit_service.dart';
import '../src/service/fake_github_service.dart';
import '../src/service/fake_luci_build_service.dart';
import '../src/utilities/entity_generators.dart';
import '../src/utilities/mocks.dart';

const String singleCiYaml = r'''
enabled_branches:
  - master
  - main
  - flutter-\d+\.\d+-candidate\.\d+
targets:
  - name: Linux A
    properties:
      custom: abc
  - name: Linux B
    enabled_branches:
      - stable
    scheduler: luci
  - name: Linux runIf
    runIf:
      - dev/**
  - name: Google Internal Roll
    postsubmit: true
    presubmit: false
    scheduler: google_internal
''';

void main() {
  late CacheService cache;
  late FakeConfig config;
  late FakeDatastoreDB db;
  late FakeBuildStatusService buildStatusService;
  late MockClient httpClient;
  late MockGithubChecksUtil mockGithubChecksUtil;
  late Scheduler scheduler;

  final PullRequest pullRequest = generatePullRequest(id: 42);

  Commit shaToCommit(String sha, {String branch = 'master'}) {
    return Commit(
      key: db.emptyKey.append(Commit, id: 'flutter/flutter/$branch/$sha'),
      repository: 'flutter/flutter',
      sha: sha,
      branch: branch,
      timestamp: int.parse(sha),
    );
  }

  group('Scheduler', () {
    setUp(() {
      final MockTabledataResource tabledataResource = MockTabledataResource();
      when(tabledataResource.insertAll(any, any, any, any)).thenAnswer((_) async {
        return TableDataInsertAllResponse();
      });

      cache = CacheService(inMemory: true);
      db = FakeDatastoreDB();
      buildStatusService =
          FakeBuildStatusService(commitStatuses: <CommitStatus>[CommitStatus(generateCommit(1), const <Stage>[])]);
      config = FakeConfig(
        tabledataResource: tabledataResource,
        dbValue: db,
        githubService: FakeGithubService(),
        githubClient: MockGitHub(),
        supportedReposValue: <RepositorySlug>{
          Config.engineSlug,
          Config.flutterSlug,
        },
      );
      httpClient = MockClient((http.Request request) async {
        if (request.url.path.contains('.ci.yaml')) {
          return http.Response(singleCiYaml, 200);
        }
        throw Exception('Failed to find ${request.url.path}');
      });

      mockGithubChecksUtil = MockGithubChecksUtil();
      // Generate check runs based on the name hash code
      when(mockGithubChecksUtil.createCheckRun(any, any, any, any, output: anyNamed('output')))
          .thenAnswer((Invocation invocation) async => generateCheckRun(invocation.positionalArguments[2].hashCode));
      scheduler = Scheduler(
        cache: cache,
        config: config,
        datastoreProvider: (DatastoreDB db) => DatastoreService(db, 2),
        buildStatusProvider: (_) => buildStatusService,
        githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
        httpClientProvider: () => httpClient,
        luciBuildService: FakeLuciBuildService(
          config: config,
          githubChecksUtil: mockGithubChecksUtil,
          gerritService: FakeGerritService(
            branchesValue: <String>['master'],
          ),
        ),
      );

      when(mockGithubChecksUtil.createCheckRun(any, any, any, any)).thenAnswer((_) async {
        return CheckRun.fromJson(const <String, dynamic>{
          'id': 1,
          'started_at': '2020-05-10T02:49:31Z',
          'check_suite': <String, dynamic>{'id': 2}
        });
      });
    });

    group('add commits', () {
      final FakePubSub pubsub = FakePubSub();
      List<Commit> createCommitList(
        List<String> shas, {
        String repo = 'flutter',
      }) {
        return List<Commit>.generate(
          shas.length,
          (int index) => Commit(
            author: 'Username',
            authorAvatarUrl: 'http://example.org/avatar.jpg',
            branch: 'master',
            key: db.emptyKey.append(Commit, id: 'flutter/$repo/master/${shas[index]}'),
            message: 'commit message',
            repository: 'flutter/$repo',
            sha: shas[index],
            timestamp: DateTime.fromMillisecondsSinceEpoch(int.parse(shas[index])).millisecondsSinceEpoch,
          ),
        );
      }

      test('succeeds when GitHub returns no commits', () async {
        await scheduler.addCommits(<Commit>[]);
        expect(db.values, isEmpty);
      });

      test('inserts all relevant fields of the commit', () async {
        config.supportedBranchesValue = <String>['master'];
        expect(db.values.values.whereType<Commit>().length, 0);
        await scheduler.addCommits(createCommitList(<String>['1']));
        expect(db.values.values.whereType<Commit>().length, 1);
        final Commit commit = db.values.values.whereType<Commit>().single;
        expect(commit.repository, 'flutter/flutter');
        expect(commit.branch, 'master');
        expect(commit.sha, '1');
        expect(commit.timestamp, 1);
        expect(commit.author, 'Username');
        expect(commit.authorAvatarUrl, 'http://example.org/avatar.jpg');
        expect(commit.message, 'commit message');
      });

      test('skips scheduling for unsupported repos', () async {
        config.supportedBranchesValue = <String>['master'];
        await scheduler.addCommits(createCommitList(<String>['1'], repo: 'not-supported'));
        expect(db.values.values.whereType<Commit>().length, 0);
      });

      test('skips commits for which transaction commit fails', () async {
        config.supportedBranchesValue = <String>['master'];

        // Existing commits should not be duplicated.
        final Commit commit = shaToCommit('1');
        db.values[commit.key] = commit;

        db.onCommit = (List<gcloud_db.Model<dynamic>> inserts, List<gcloud_db.Key<dynamic>> deletes) {
          if (inserts.whereType<Commit>().where((Commit commit) => commit.sha == '3').isNotEmpty) {
            throw StateError('Commit failed');
          }
        };
        // Commits are expect from newest to oldest timestamps
        await scheduler.addCommits(createCommitList(<String>['2', '3', '4']));
        expect(db.values.values.whereType<Commit>().length, 3);
        // The 2 new commits are scheduled 3 tasks, existing commit has none.
        expect(db.values.values.whereType<Task>().length, 2 * 3);
        // Check commits were added, but 3 was not
        expect(db.values.values.whereType<Commit>().map<String>(toSha), containsAll(<String>['1', '2', '4']));
        expect(db.values.values.whereType<Commit>().map<String>(toSha), isNot(contains('3')));
      });

      test('skips commits for which task transaction fails', () async {
        config.supportedBranchesValue = <String>['master'];

        // Existing commits should not be duplicated.
        final Commit commit = shaToCommit('1');
        db.values[commit.key] = commit;

        db.onCommit = (List<gcloud_db.Model<dynamic>> inserts, List<gcloud_db.Key<dynamic>> deletes) {
          if (inserts.whereType<Task>().where((Task task) => task.createTimestamp == 3).isNotEmpty) {
            throw StateError('Task failed');
          }
        };
        // Commits are expect from newest to oldest timestamps
        await scheduler.addCommits(createCommitList(<String>['2', '3', '4']));
        expect(db.values.values.whereType<Commit>().length, 3);
        // The 2 new commits are scheduled 3 tasks, existing commit has none.
        expect(db.values.values.whereType<Task>().length, 2 * 3);
        // Check commits were added, but 3 was not
        expect(db.values.values.whereType<Commit>().map<String>(toSha), containsAll(<String>['1', '2', '4']));
        expect(db.values.values.whereType<Commit>().map<String>(toSha), isNot(contains('3')));
      });

      test('schedules cocoon based targets', () async {
        final MockLuciBuildService luciBuildService = MockLuciBuildService();
        when(
          luciBuildService.schedulePostsubmitBuilds(
            commit: anyNamed('commit'),
            toBeScheduled: captureAnyNamed('toBeScheduled'),
          ),
        ).thenAnswer((_) => Future<void>.value());
        buildStatusService =
            FakeBuildStatusService(commitStatuses: <CommitStatus>[CommitStatus(generateCommit(1), const <Stage>[])]);
        scheduler = Scheduler(
          cache: cache,
          config: config,
          buildStatusProvider: (_) => buildStatusService,
          datastoreProvider: (DatastoreDB db) => DatastoreService(db, 2),
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          httpClientProvider: () => httpClient,
          luciBuildService: luciBuildService,
        );

        await scheduler.addCommits(createCommitList(<String>['1']));
        final List<dynamic> captured = verify(
          luciBuildService.schedulePostsubmitBuilds(
            commit: anyNamed('commit'),
            toBeScheduled: captureAnyNamed('toBeScheduled'),
          ),
        ).captured;
        final List<dynamic> toBeScheduled = captured.first as List<dynamic>;
        expect(toBeScheduled.length, 2);
        final Iterable<Tuple<Target, Task, int>> tuples =
            toBeScheduled.map((dynamic tuple) => tuple as Tuple<Target, Task, int>);
        final Iterable<String> scheduledTargetNames =
            tuples.map((Tuple<Target, Task, int> tuple) => tuple.second.name!);
        expect(scheduledTargetNames, ['Linux A', 'Linux runIf']);
        // Tasks triggered by cocoon are marked as in progress
        final Iterable<Task> tasks = db.values.values.whereType<Task>();
        expect(tasks.singleWhere((Task task) => task.name == 'Linux A').status, Task.statusInProgress);
      });

      test('schedules cocoon based targets - multiple batch requests', () async {
        final MockBuildBucketClient mockBuildBucketClient = MockBuildBucketClient();
        final FakeLuciBuildService luciBuildService = FakeLuciBuildService(
          config: config,
          buildbucket: mockBuildBucketClient,
          gerritService: FakeGerritService(),
          githubChecksUtil: mockGithubChecksUtil,
          pubsub: pubsub,
        );
        when(mockGithubChecksUtil.createCheckRun(any, any, any, any, output: anyNamed('output')))
            .thenAnswer((_) async => generateCheckRun(1, name: 'Linux A'));
        when(mockBuildBucketClient.listBuilders(any)).thenAnswer((_) async {
          return const ListBuildersResponse(
            builders: [
              BuilderItem(id: BuilderId(bucket: 'prod', project: 'flutter', builder: 'Linux A')),
              BuilderItem(id: BuilderId(bucket: 'prod', project: 'flutter', builder: 'Linux runIf')),
            ],
          );
        });
        buildStatusService =
            FakeBuildStatusService(commitStatuses: <CommitStatus>[CommitStatus(generateCommit(1), const <Stage>[])]);
        config.batchSizeValue = 1;
        scheduler = Scheduler(
          cache: cache,
          config: config,
          buildStatusProvider: (_) => buildStatusService,
          datastoreProvider: (DatastoreDB db) => DatastoreService(db, 2),
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          httpClientProvider: () => httpClient,
          luciBuildService: luciBuildService,
        );

        await scheduler.addCommits(createCommitList(<String>['1']));
        expect(pubsub.messages.length, 2);
      });
    });

    group('add pull request', () {
      test('creates expected commit', () async {
        final PullRequest mergedPr = generatePullRequest();
        await scheduler.addPullRequest(mergedPr);

        expect(db.values.values.whereType<Commit>().length, 1);
        final Commit commit = db.values.values.whereType<Commit>().single;
        expect(commit.repository, 'flutter/flutter');
        expect(commit.branch, 'master');
        expect(commit.sha, 'abc');
        expect(commit.timestamp, 1);
        expect(commit.author, 'dash');
        expect(commit.authorAvatarUrl, 'dashatar');
        expect(commit.message, 'example message');
      });

      test('schedules tasks against merged PRs', () async {
        final PullRequest mergedPr = generatePullRequest();
        await scheduler.addPullRequest(mergedPr);

        expect(db.values.values.whereType<Commit>().length, 1);
        expect(db.values.values.whereType<Task>().length, 3);
      });

      test('gurantees scheduling of tasks against merged release branch PR', () async {
        final PullRequest mergedPr = generatePullRequest(branch: 'flutter-3.2-candidate.5');
        await scheduler.addPullRequest(mergedPr);

        expect(db.values.values.whereType<Commit>().length, 1);
        expect(db.values.values.whereType<Task>().length, 3);
        // Ensure all tasks have been marked in progress
        expect(db.values.values.whereType<Task>().where((Task task) => task.status == Task.statusNew), isEmpty);
      });

      test('gurantees scheduling of tasks against merged engine PR', () async {
        final PullRequest mergedPr = generatePullRequest(
          repo: Config.engineSlug.name,
          branch: Config.defaultBranch(Config.engineSlug),
        );
        await scheduler.addPullRequest(mergedPr);

        expect(db.values.values.whereType<Commit>().length, 1);
        expect(db.values.values.whereType<Task>().length, 3);
        // Ensure all tasks have been marked in progress
        expect(db.values.values.whereType<Task>().where((Task task) => task.status == Task.statusNew), isEmpty);
      });

      test('does not schedule tasks against non-merged PRs', () async {
        final PullRequest notMergedPr = generatePullRequest(merged: false);
        await scheduler.addPullRequest(notMergedPr);

        expect(db.values.values.whereType<Commit>().map<String>(toSha).length, 0);
        expect(db.values.values.whereType<Task>().length, 0);
      });

      test('does not schedule tasks against already added PRs', () async {
        // Existing commits should not be duplicated.
        final Commit commit = shaToCommit('1');
        db.values[commit.key] = commit;

        final PullRequest alreadyLandedPr = generatePullRequest(sha: '1');
        await scheduler.addPullRequest(alreadyLandedPr);

        expect(db.values.values.whereType<Commit>().map<String>(toSha).length, 1);
        // No tasks should be scheduled as that is done on commit insert.
        expect(db.values.values.whereType<Task>().length, 0);
      });

      test('creates expected commit from release branch PR', () async {
        final PullRequest mergedPr = generatePullRequest(branch: '1.26');
        await scheduler.addPullRequest(mergedPr);

        expect(db.values.values.whereType<Commit>().length, 1);
        final Commit commit = db.values.values.whereType<Commit>().single;
        expect(commit.repository, 'flutter/flutter');
        expect(commit.branch, '1.26');
        expect(commit.sha, 'abc');
        expect(commit.timestamp, 1);
        expect(commit.author, 'dash');
        expect(commit.authorAvatarUrl, 'dashatar');
        expect(commit.message, 'example message');
      });
    });

    group('process check run', () {
      test('rerequested ci.yaml check retriggers presubmit', () async {
        final MockGithubService mockGithubService = MockGithubService();
        final MockGitHub mockGithubClient = MockGitHub();
        buildStatusService =
            FakeBuildStatusService(commitStatuses: <CommitStatus>[CommitStatus(generateCommit(1), const <Stage>[])]);
        config = FakeConfig(
          githubService: mockGithubService,
        );
        scheduler = Scheduler(
          cache: cache,
          config: config,
          buildStatusProvider: (_) => buildStatusService,
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          httpClientProvider: () => httpClient,
          luciBuildService: FakeLuciBuildService(
            config: config,
            githubChecksUtil: mockGithubChecksUtil,
          ),
        );
        when(mockGithubService.github).thenReturn(mockGithubClient);
        when(mockGithubService.searchIssuesAndPRs(any, any, sort: anyNamed('sort'), pages: anyNamed('pages')))
            .thenAnswer((_) async => [generateIssue(3)]);
        when(mockGithubChecksUtil.listCheckSuitesForRef(any, any, ref: anyNamed('ref'))).thenAnswer(
          (_) async => [
            // From check_run.check_suite.id in [checkRunString].
            generateCheckSuite(668083231)
          ],
        );
        when(mockGithubService.getPullRequest(any, any)).thenAnswer((_) async => generatePullRequest());
        when(mockGithubService.listFiles(any)).thenAnswer((_) async => ['abc/def']);
        when(
          mockGithubChecksUtil.createCheckRun(
            any,
            any,
            any,
            any,
            output: anyNamed('output'),
          ),
        ).thenAnswer((_) async {
          return CheckRun.fromJson(const <String, dynamic>{
            'id': 1,
            'started_at': '2020-05-10T02:49:31Z',
            'name': Scheduler.kCiYamlCheckName,
            'check_suite': <String, dynamic>{'id': 2}
          });
        });
        final Map<String, dynamic> checkRunEventJson = jsonDecode(checkRunString) as Map<String, dynamic>;
        checkRunEventJson['check_run']['name'] = Scheduler.kCiYamlCheckName;
        final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(checkRunEventJson);
        expect(await scheduler.processCheckRun(checkRunEvent), true);
        verify(
          mockGithubChecksUtil.createCheckRun(
            any,
            any,
            any,
            Scheduler.kCiYamlCheckName,
            output: anyNamed('output'),
          ),
        );
        // Verfies Linux A was created
        verify(mockGithubChecksUtil.createCheckRun(any, any, any, any)).called(1);
      });

      test('rerequested presubmit check triggers presubmit build', () async {
        // Note that we're not inserting any commits into the db, because
        // only postsubmit commits are stored in the datastore.
        config = FakeConfig(dbValue: db);
        db = FakeDatastoreDB();

        // Set up mock buildbucket to validate which bucket is requested.
        final MockBuildBucketClient mockBuildbucket = MockBuildBucketClient();
        when(mockBuildbucket.batch(any)).thenAnswer((i) async {
          return FakeBuildBucketClient().batch(i.positionalArguments[0]);
        });
        when(mockBuildbucket.scheduleBuild(any, buildBucketUri: anyNamed('buildBucketUri')))
            .thenAnswer((realInvocation) async {
          final ScheduleBuildRequest scheduleBuildRequest = realInvocation.positionalArguments[0];
          // Ensure this is an attempt to schedule a presubmit build by
          // verifying that bucket == 'try'.
          expect(scheduleBuildRequest.builderId.bucket, equals('try'));
          return const Build(builderId: BuilderId(), id: '');
        });

        scheduler = Scheduler(
          cache: cache,
          config: config,
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          luciBuildService: FakeLuciBuildService(
            config: config,
            githubChecksUtil: mockGithubChecksUtil,
            buildbucket: mockBuildbucket,
          ),
        );
        final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(
          jsonDecode(checkRunString) as Map<String, dynamic>,
        );
        expect(await scheduler.processCheckRun(checkRunEvent), true);
        verify(mockBuildbucket.scheduleBuild(any, buildBucketUri: anyNamed('buildBucketUri'))).called(1);
        verify(mockGithubChecksUtil.createCheckRun(any, any, any, any)).called(1);
      });

      test('rerequested postsubmit check triggers postsubmit build', () async {
        // Set up datastore with postsubmit entities matching [checkRunString].
        db = FakeDatastoreDB();
        config = FakeConfig(dbValue: db, postsubmitSupportedReposValue: {RepositorySlug('abc', 'cocoon')});
        final Commit commit = generateCommit(
          1,
          sha: '66d6bd9a3f79a36fe4f5178ccefbc781488a596c',
          branch: 'independent_agent',
          owner: 'abc',
          repo: 'cocoon',
        );
        config.db.values[commit.key] = commit;
        final Task task = generateTask(1, name: "test1", parent: commit);
        config.db.values[task.key] = task;

        // Set up ci.yaml with task name and branch name from [checkRunString].
        httpClient = MockClient((http.Request request) async {
          if (request.url.path.contains('.ci.yaml')) {
            return http.Response(
              r'''
enabled_branches:
  - independent_agent
targets:
  - name: test1
''',
              200,
            );
          }
          throw Exception('Failed to find ${request.url.path}');
        });

        // Set up mock buildbucket to validate which bucket is requested.
        final MockBuildBucketClient mockBuildbucket = MockBuildBucketClient();
        when(mockBuildbucket.batch(any)).thenAnswer((i) async {
          return FakeBuildBucketClient().batch(i.positionalArguments[0]);
        });
        when(mockBuildbucket.scheduleBuild(any, buildBucketUri: anyNamed('buildBucketUri')))
            .thenAnswer((realInvocation) async {
          final ScheduleBuildRequest scheduleBuildRequest = realInvocation.positionalArguments[0];
          // Ensure this is an attempt to schedule a postsubmit build by
          // verifying that bucket == 'prod'.
          expect(scheduleBuildRequest.builderId.bucket, equals('prod'));
          return const Build(builderId: BuilderId(), id: '');
        });

        scheduler = Scheduler(
          cache: cache,
          config: config,
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          httpClientProvider: () => httpClient,
          luciBuildService: FakeLuciBuildService(
            config: config,
            githubChecksUtil: mockGithubChecksUtil,
            buildbucket: mockBuildbucket,
          ),
        );
        final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(
          jsonDecode(checkRunString) as Map<String, dynamic>,
        );
        expect(await scheduler.processCheckRun(checkRunEvent), true);
        verify(mockBuildbucket.scheduleBuild(any, buildBucketUri: anyNamed('buildBucketUri'))).called(1);
        verify(mockGithubChecksUtil.createCheckRun(any, any, any, any)).called(1);
      });

      test('rerequested does not fail on empty pull request list', () async {
        when(mockGithubChecksUtil.createCheckRun(any, any, any, any)).thenAnswer((_) async {
          return CheckRun.fromJson(const <String, dynamic>{
            'id': 1,
            'started_at': '2020-05-10T02:49:31Z',
            'check_suite': <String, dynamic>{'id': 2},
          });
        });
        final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(
          jsonDecode(checkRunWithEmptyPullRequests) as Map<String, dynamic>,
        );
        expect(await scheduler.processCheckRun(checkRunEvent), true);
        verify(mockGithubChecksUtil.createCheckRun(any, any, any, any)).called(1);
      });
    });

    group('presubmit', () {
      test('gets only enabled .ci.yaml builds', () async {
        httpClient = MockClient((http.Request request) async {
          if (request.url.path.contains('.ci.yaml')) {
            return http.Response(
              '''
enabled_branches:
  - master
targets:
  - name: Linux A
    presubmit: true
    scheduler: luci
  - name: Linux B
    scheduler: luci
    enabled_branches:
      - stable
    presubmit: true
  - name: Linux C
    scheduler: luci
    enabled_branches:
      - master
    presubmit: true
  - name: Linux D
    scheduler: luci
    bringup: true
    presubmit: true
  - name: Google-internal roll
    scheduler: google_internal
    enabled_branches:
      - master
    presubmit: true
          ''',
              200,
            );
          }
          throw Exception('Failed to find ${request.url.path}');
        });
        final List<Target> presubmitTargets = await scheduler.getPresubmitTargets(pullRequest);
        expect(
          presubmitTargets.map((Target target) => target.value.name).toList(),
          containsAll(<String>['Linux A', 'Linux C']),
        );
      });

      test('checks for release branches', () async {
        const String branch = 'flutter-1.24-candidate.1';
        httpClient = MockClient((http.Request request) async {
          if (request.url.path.contains('.ci.yaml')) {
            return http.Response(
              '''
enabled_branches:
  - master
targets:
  - name: Linux A
    presubmit: true
    scheduler: luci
          ''',
              200,
            );
          }
          throw Exception('Failed to find ${request.url.path}');
        });
        expect(
          scheduler.getPresubmitTargets(generatePullRequest(branch: branch)),
          throwsA(predicate((Exception e) => e.toString().contains('$branch is not enabled'))),
        );
      });

      test('checks for release branch regex', () async {
        const String branch = 'flutter-1.24-candidate.1';
        httpClient = MockClient((http.Request request) async {
          if (request.url.path.contains('.ci.yaml')) {
            return http.Response(
              '''
enabled_branches:
  - main
  - flutter-\\d+.\\d+-candidate.\\d+
targets:
  - name: Linux A
    scheduler: luci
          ''',
              200,
            );
          }
          throw Exception('Failed to find ${request.url.path}');
        });
        final List<Target> targets = await scheduler.getPresubmitTargets(generatePullRequest(branch: branch));
        expect(targets.single.value.name, 'Linux A');
      });

      test('triggers expected presubmit build checks', () async {
        await scheduler.triggerPresubmitTargets(pullRequest: pullRequest);
        expect(
          verify(mockGithubChecksUtil.createCheckRun(any, any, any, captureAny, output: captureAnyNamed('output')))
              .captured,
          <dynamic>[
            Scheduler.kCiYamlCheckName,
            const CheckRunOutput(
              title: Scheduler.kCiYamlCheckName,
              summary: 'If this check is stuck pending, push an empty commit to retrigger the checks',
            ),
            'Linux A',
            null,
            // Linux runIf is not run as this is for tip of tree and the files weren't affected
          ],
        );
      });

      test('triggers all presubmit build checks when diff cannot be found', () async {
        final MockGithubService mockGithubService = MockGithubService();
        when(mockGithubService.listFiles(pullRequest))
            .thenThrow(GitHubError(GitHub(), 'Requested Resource was Not Found'));
        buildStatusService =
            FakeBuildStatusService(commitStatuses: <CommitStatus>[CommitStatus(generateCommit(1), const <Stage>[])]);
        scheduler = Scheduler(
          cache: cache,
          config: FakeConfig(
            // tabledataResource: tabledataResource,
            dbValue: db,
            githubService: mockGithubService,
            githubClient: MockGitHub(),
          ),
          buildStatusProvider: (_) => buildStatusService,
          datastoreProvider: (DatastoreDB db) => DatastoreService(db, 2),
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          httpClientProvider: () => httpClient,
          luciBuildService: FakeLuciBuildService(
            config: config,
            githubChecksUtil: mockGithubChecksUtil,
            gerritService: FakeGerritService(branchesValue: <String>['master']),
          ),
        );
        await scheduler.triggerPresubmitTargets(pullRequest: pullRequest);
        expect(
          verify(mockGithubChecksUtil.createCheckRun(any, any, any, captureAny, output: captureAnyNamed('output')))
              .captured,
          <dynamic>[
            Scheduler.kCiYamlCheckName,
            const CheckRunOutput(
              title: Scheduler.kCiYamlCheckName,
              summary: 'If this check is stuck pending, push an empty commit to retrigger the checks',
            ),
            'Linux A',
            null,
            // runIf requires a diff in dev, so an error will cause it to be triggered
            'Linux runIf',
            null
          ],
        );
      });

      test('triggers all presubmit targets on release branch pull request', () async {
        final PullRequest releasePullRequest = generatePullRequest(
          branch: 'flutter-1.24-candidate.1',
        );
        await scheduler.triggerPresubmitTargets(pullRequest: releasePullRequest);
        expect(
          verify(mockGithubChecksUtil.createCheckRun(any, any, any, captureAny, output: captureAnyNamed('output')))
              .captured,
          <dynamic>[
            Scheduler.kCiYamlCheckName,
            const CheckRunOutput(
              title: Scheduler.kCiYamlCheckName,
              summary: 'If this check is stuck pending, push an empty commit to retrigger the checks',
            ),
            'Linux A',
            null,
            'Linux runIf',
            null,
          ],
        );
      });

      test('ci.yaml validation passes with default config', () async {
        when(mockGithubChecksUtil.getCheckRun(any, any, any))
            .thenAnswer((Invocation invocation) async => createCheckRun(id: 0));
        await scheduler.triggerPresubmitTargets(pullRequest: pullRequest);
        expect(
          verify(
            mockGithubChecksUtil.updateCheckRun(
              any,
              any,
              any,
              status: captureAnyNamed('status'),
              conclusion: captureAnyNamed('conclusion'),
              output: anyNamed('output'),
            ),
          ).captured,
          <dynamic>[CheckRunStatus.completed, CheckRunConclusion.success],
        );
      });

      test('ci.yaml validation fails with empty config', () async {
        httpClient = MockClient((http.Request request) async {
          if (request.url.path.contains('.ci.yaml')) {
            return http.Response('', 200);
          }
          throw Exception('Failed to find ${request.url.path}');
        });
        await scheduler.triggerPresubmitTargets(pullRequest: pullRequest);
        expect(
          verify(
            mockGithubChecksUtil.updateCheckRun(
              any,
              any,
              any,
              status: captureAnyNamed('status'),
              conclusion: captureAnyNamed('conclusion'),
              output: anyNamed('output'),
            ),
          ).captured,
          <dynamic>[CheckRunStatus.completed, CheckRunConclusion.failure],
        );
      });

      test('ci.yaml validation fails on not enabled branch', () async {
        final PullRequest pullRequest = generatePullRequest(branch: 'not-valid');
        await scheduler.triggerPresubmitTargets(pullRequest: pullRequest);
        expect(
          verify(
            mockGithubChecksUtil.updateCheckRun(
              any,
              any,
              any,
              status: captureAnyNamed('status'),
              conclusion: captureAnyNamed('conclusion'),
              output: anyNamed('output'),
            ),
          ).captured,
          <dynamic>[CheckRunStatus.completed, CheckRunConclusion.failure],
        );
      });

      test('ci.yaml validation fails with config with unknown dependencies', () async {
        httpClient = MockClient((http.Request request) async {
          if (request.url.path.contains('.ci.yaml')) {
            return http.Response(
              '''
enabled_branches:
  - master
targets:
  - name: A
    builder: Linux A
    dependencies:
      - B
          ''',
              200,
            );
          }
          throw Exception('Failed to find ${request.url.path}');
        });
        await scheduler.triggerPresubmitTargets(pullRequest: pullRequest);
        expect(
          verify(
            mockGithubChecksUtil.updateCheckRun(
              any,
              any,
              any,
              status: anyNamed('status'),
              conclusion: anyNamed('conclusion'),
              output: captureAnyNamed('output'),
            ),
          ).captured.first.text,
          'FormatException: ERROR: A depends on B which does not exist',
        );
      });

      test('retries only triggers failed builds only', () async {
        final MockBuildBucketClient mockBuildbucket = MockBuildBucketClient();
        buildStatusService =
            FakeBuildStatusService(commitStatuses: <CommitStatus>[CommitStatus(generateCommit(1), const <Stage>[])]);
        final FakePubSub pubsub = FakePubSub();
        scheduler = Scheduler(
          cache: cache,
          config: config,
          datastoreProvider: (DatastoreDB db) => DatastoreService(db, 2),
          githubChecksService: GithubChecksService(config, githubChecksUtil: mockGithubChecksUtil),
          buildStatusProvider: (_) => buildStatusService,
          httpClientProvider: () => httpClient,
          luciBuildService: FakeLuciBuildService(
            config: config,
            githubChecksUtil: mockGithubChecksUtil,
            buildbucket: mockBuildbucket,
            gerritService: FakeGerritService(branchesValue: <String>['master']),
            pubsub: pubsub,
          ),
        );
        when(mockBuildbucket.batch(any)).thenAnswer(
          (_) async => BatchResponse(
            responses: <Response>[
              Response(
                searchBuilds: SearchBuildsResponse(
                  builds: <Build>[
                    generateBuild(1000, name: 'Linux', bucket: 'try'),
                    generateBuild(2000, name: 'Linux Coverage', bucket: 'try'),
                    generateBuild(3000, name: 'Mac', bucket: 'try', status: Status.scheduled),
                    generateBuild(4000, name: 'Windows', bucket: 'try', status: Status.started),
                    generateBuild(5000, name: 'Linux A', bucket: 'try', status: Status.failure)
                  ],
                ),
              ),
            ],
          ),
        );
        when(mockBuildbucket.scheduleBuild(any))
            .thenAnswer((_) async => generateBuild(5001, name: 'Linux A', bucket: 'try', status: Status.scheduled));
        // Only Linux A should be retried
        final Map<String, CheckRun> checkRuns = <String, CheckRun>{
          'Linux': createCheckRun(name: 'Linux', id: 100),
          'Linux Coverage': createCheckRun(name: 'Linux Coverage', id: 200),
          'Mac': createCheckRun(name: 'Mac', id: 300, status: CheckRunStatus.queued),
          'Windows': createCheckRun(name: 'Windows', id: 400, status: CheckRunStatus.inProgress),
          'Linux A': createCheckRun(name: 'Linux A', id: 500),
        };
        when(mockGithubChecksUtil.allCheckRuns(any, any)).thenAnswer((_) async {
          return checkRuns;
        });

        final CheckSuiteEvent checkSuiteEvent =
            CheckSuiteEvent.fromJson(jsonDecode(checkSuiteTemplate('rerequested')) as Map<String, dynamic>);
        await scheduler.retryPresubmitTargets(
          pullRequest: pullRequest,
          checkSuiteEvent: checkSuiteEvent,
        );

        expect(pubsub.messages.length, 1);
        final BatchRequest batchRequest = pubsub.messages.single as BatchRequest;
        expect(batchRequest.requests!.length, 1);
        // Schedule build should have been sent
        expect(batchRequest.requests!.single.scheduleBuild, isNotNull);
        final ScheduleBuildRequest scheduleBuildRequest = batchRequest.requests!.single.scheduleBuild!;
        // Verify expected parameters to schedule build
        expect(scheduleBuildRequest.builderId.builder, 'Linux A');
        expect(scheduleBuildRequest.properties!['custom'], 'abc');
      });

      test('triggers only specificed targets', () async {
        final List<Target> presubmitTargets = <Target>[generateTarget(1), generateTarget(2)];
        final List<Target> presubmitTriggerTargets = scheduler.getTriggerList(presubmitTargets, <String>['Linux 1']);
        expect(presubmitTriggerTargets.length, 1);
      });

      test('triggers all presubmit targets when trigger list is null', () async {
        final List<Target> presubmitTargets = <Target>[generateTarget(1), generateTarget(2)];
        final List<Target> presubmitTriggerTargets = scheduler.getTriggerList(presubmitTargets, null);
        expect(presubmitTriggerTargets.length, 2);
      });

      test('triggers all presubmit targets when trigger list is empty', () async {
        final List<Target> presubmitTargets = <Target>[generateTarget(1), generateTarget(2)];
        final List<Target> presubmitTriggerTargets = scheduler.getTriggerList(presubmitTargets, <String>[]);
        expect(presubmitTriggerTargets.length, 2);
      });

      test('triggers only targets that are contained in the trigger list', () async {
        final List<Target> presubmitTargets = <Target>[generateTarget(1), generateTarget(2)];
        final List<Target> presubmitTriggerTargets =
            scheduler.getTriggerList(presubmitTargets, <String>['Linux 1', 'Linux 3']);
        expect(presubmitTriggerTargets.length, 1);
        expect(presubmitTargets[0].value.name, 'Linux 1');
      });
    });
  });
}

CheckRun createCheckRun({String? name, required int id, CheckRunStatus status = CheckRunStatus.completed}) {
  final int externalId = id * 2;
  final String checkRunJson =
      '{"name": "$name", "id": $id, "external_id": "{$externalId}", "status": "$status", "started_at": "2020-05-10T02:49:31Z", "head_sha": "the_sha", "check_suite": {"id": 456}}';
  return CheckRun.fromJson(jsonDecode(checkRunJson) as Map<String, dynamic>);
}

String toSha(Commit commit) => commit.sha!;

int toTimestamp(Commit commit) => commit.timestamp!;
