// 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 'package:cocoon_service/src/model/appengine/commit.dart';
import 'package:cocoon_service/src/request_handlers/vacuum_github_commits.dart';
import 'package:cocoon_service/src/request_handling/body.dart';
import 'package:cocoon_service/src/service/config.dart';
import 'package:cocoon_service/src/service/datastore.dart';
import 'package:gcloud/db.dart' as gcloud_db;
import 'package:gcloud/db.dart';
import 'package:github/github.dart';
import 'package:googleapis/bigquery/v2.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../src/datastore/fake_config.dart';
import '../src/datastore/fake_datastore.dart';
import '../src/request_handling/api_request_handler_tester.dart';
import '../src/request_handling/fake_authentication.dart';
import '../src/service/fake_github_service.dart';
import '../src/service/fake_scheduler.dart';
import '../src/utilities/mocks.dart';

void main() {
  group('VacuumGithubCommits', () {
    late FakeConfig config;
    FakeAuthenticationProvider auth;
    late FakeDatastoreDB db;
    FakeScheduler scheduler;
    late ApiRequestHandlerTester tester;
    late VacuumGithubCommits handler;

    late List<String> githubCommits;
    late int yieldedCommitCount;

    List<RepositoryCommit> commitList() {
      final List<RepositoryCommit> commits = <RepositoryCommit>[];
      for (String sha in githubCommits) {
        final User author = User()
          ..login = 'Username'
          ..avatarUrl = 'http://example.org/avatar.jpg';
        final GitCommitUser committer =
            GitCommitUser('Username', 'Username@abc.com', DateTime.fromMillisecondsSinceEpoch(int.parse(sha)));
        final GitCommit gitCommit = GitCommit()
          ..message = 'commit message'
          ..committer = committer;
        commits.add(
          RepositoryCommit()
            ..sha = sha
            ..author = author
            ..commit = gitCommit,
        );
      }
      return commits;
    }

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

    setUp(() {
      final MockRepositoriesService repositories = MockRepositoriesService();
      final FakeGithubService githubService = FakeGithubService();
      final MockTabledataResource tabledataResourceApi = MockTabledataResource();
      when(tabledataResourceApi.insertAll(any, any, any, any)).thenAnswer((_) async {
        return TableDataInsertAllResponse();
      });

      yieldedCommitCount = 0;
      db = FakeDatastoreDB();
      config = FakeConfig(
        tabledataResource: tabledataResourceApi,
        githubService: githubService,
        dbValue: db,
        supportedBranchesValue: <String>[
          'master',
          'main',
        ],
        supportedReposValue: <RepositorySlug>{
          Config.cocoonSlug,
          Config.engineSlug,
          Config.flutterSlug,
          Config.packagesSlug,
          Config.pluginsSlug,
        },
      );

      auth = FakeAuthenticationProvider();
      scheduler = FakeScheduler(
        config: config,
        ciYaml: exampleConfig,
      );
      tester = ApiRequestHandlerTester();
      handler = VacuumGithubCommits(
        config: config,
        authenticationProvider: auth,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        scheduler: scheduler,
      );

      githubService.listCommitsBranch = (String branch, int hours) {
        return commitList();
      };

      when(githubService.github.repositories).thenReturn(repositories);
    });

    test('succeeds when GitHub returns no commits', () async {
      githubCommits = <String>[];
      config.supportedBranchesValue = <String>['master'];
      final Body body = await tester.get<Body>(handler);
      expect(yieldedCommitCount, 0);
      expect(db.values, isEmpty);
      expect(await body.serialize().toList(), isEmpty);
    });

    test('does not fail on empty commit list', () async {
      githubCommits = <String>[];
      expect(db.values.values.whereType<Commit>().length, 0);
      await tester.get<Body>(handler);
      expect(db.values.values.whereType<Commit>().length, 0);
    });

    test('does not add recent commits', () async {
      githubCommits = <String>['${DateTime.now().millisecondsSinceEpoch}'];

      expect(db.values.values.whereType<Commit>().length, 0);
      await tester.get<Body>(handler);
      expect(db.values.values.whereType<Commit>().length, 0);
    });

    test('inserts all relevant fields of the commit', () async {
      githubCommits = <String>['1'];
      expect(db.values.values.whereType<Commit>().length, 0);
      await tester.get<Body>(handler);
      expect(db.values.values.whereType<Commit>().length, config.supportedRepos.length);
      final List<Commit> commits = db.values.values.whereType<Commit>().toList();
      final Commit commit = commits.first;
      expect(commit.repository, 'flutter/cocoon');
      expect(commit.branch, 'main');
      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');
      expect(commits[1].repository, Config.engineSlug.fullName);
      expect(commits[2].repository, Config.flutterSlug.fullName);
    });

    test('skips commits for which transaction commit fails', () async {
      githubCommits = <String>['2', '3', '4'];

      /// This test is simulating an existing branch, which must already
      /// have at least one commit in the datastore.
      final Commit commit = shaToCommit('1', 'main', Config.engineSlug);
      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');
        }
      };
      final Body body = await tester.get<Body>(handler);

      /// The +1 is coming from the engine repository and manually added commit on the top of this test.
      expect(db.values.values.whereType<Commit>().length, 10 + 1); // 2 commits for 5 repos
      expect(db.values.values.whereType<Commit>().map<String>(toSha), containsAll(<String>['1', '2', '4']));
      expect(db.values.values.whereType<Commit>().map<int>(toTimestamp), containsAll(<int>[1, 2, 4]));
      expect(await body.serialize().toList(), isEmpty);
    });
  });
}

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

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