// 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/github_build_status_update.dart';
import 'package:cocoon_service/src/request_handlers/push_build_status_to_github.dart';
import 'package:cocoon_service/src/request_handling/body.dart';
import 'package:cocoon_service/src/service/build_status_provider.dart';
import 'package:cocoon_service/src/service/config.dart';
import 'package:cocoon_service/src/service/datastore.dart';
import 'package:gcloud/db.dart';
import 'package:github/github.dart';
import 'package:googleapis/bigquery/v2.dart' hide Model;
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../src/bigquery/fake_tabledata_resource.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_build_status_provider.dart';
import '../src/service/fake_github_service.dart';
import '../src/utilities/entity_generators.dart';
import '../src/utilities/mocks.dart';

void main() {
  group('PushStatusToGithub', () {
    late FakeBuildStatusService buildStatusService;
    late FakeClientContext clientContext;
    late FakeConfig config;
    late FakeDatastoreDB db;
    late ApiRequestHandlerTester tester;
    late FakeAuthenticatedContext authContext;
    late FakeTabledataResource tabledataResourceApi;
    late PushBuildStatusToGithub handler;
    late MockGitHub github;
    late MockPullRequestsService pullRequestsService;
    late MockIssuesService issuesService;
    late MockRepositoriesService repositoriesService;
    late FakeGithubService githubService;

    GithubBuildStatusUpdate newStatusUpdate(PullRequest pr, BuildStatus status) {
      return GithubBuildStatusUpdate(
        key: db.emptyKey.append(GithubBuildStatusUpdate, id: pr.number),
        repository: Config.flutterSlug.fullName,
        status: status.githubStatus,
        pr: pr.number!,
        head: pr.head!.sha,
        updates: 0,
      );
    }

    setUp(() async {
      clientContext = FakeClientContext();
      authContext = FakeAuthenticatedContext(clientContext: clientContext);
      clientContext.isDevelopmentEnvironment = false;
      buildStatusService = FakeBuildStatusService();
      githubService = FakeGithubService();
      tabledataResourceApi = FakeTabledataResource();
      db = FakeDatastoreDB();
      github = MockGitHub();
      pullRequestsService = MockPullRequestsService();
      issuesService = MockIssuesService();
      repositoriesService = MockRepositoriesService();
      config = FakeConfig(
        tabledataResource: tabledataResourceApi,
        githubService: githubService,
        dbValue: db,
        githubClient: github,
      );
      tester = ApiRequestHandlerTester(context: authContext);
      handler = PushBuildStatusToGithub(
        config: config,
        authenticationProvider: FakeAuthenticationProvider(clientContext: clientContext),
        buildStatusServiceProvider: (_) => buildStatusService,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
      );

      when(github.pullRequests).thenReturn(pullRequestsService);
      when(github.issues).thenReturn(issuesService);
      when(github.repositories).thenReturn(repositoriesService);
      when(repositoriesService.createStatus(any, any, any)).thenAnswer(
        (_) async => RepositoryStatus(),
      );
    });

    test('development environment does nothing', () async {
      clientContext.isDevelopmentEnvironment = true;
      config.githubClient = ThrowingGitHub();
      db.onCommit = (List<Model<dynamic>> insert, List<Key<dynamic>> deletes) => throw AssertionError();
      db.addOnQuery<GithubBuildStatusUpdate>((Iterable<GithubBuildStatusUpdate> results) {
        throw AssertionError();
      });
      final Body body = await tester.get<Body>(handler);
      expect(body, same(Body.empty));
    });

    group('does not update anything', () {
      setUp(() {
        db.onCommit = (List<Model<dynamic>> insert, List<Key<dynamic>> deletes) => throw AssertionError();
        when(repositoriesService.createStatus(any, any, any)).thenThrow(AssertionError());
      });

      test('if there are no PRs', () async {
        when(pullRequestsService.list(any, base: anyNamed('base')))
            .thenAnswer((_) => const Stream<PullRequest>.empty());
        buildStatusService.cumulativeStatus = BuildStatus.success();
        final Body body = await tester.get<Body>(handler);
        final TableDataList tableDataList = await tabledataResourceApi.list('test', 'test', 'test');
        expect(body, same(Body.empty));

        // Test for BigQuery insert
        expect(tableDataList.totalRows, '1');
      });

      test('only if pull request is for the default branch', () async {
        when(pullRequestsService.list(any)).thenAnswer(
          (_) => Stream<PullRequest>.value(
            generatePullRequest(
              id: 1,
              branch: 'flutter-2.15-candidate.3',
            ),
          ),
        );
        buildStatusService.cumulativeStatus = BuildStatus.success();
        await tester.get<Body>(handler);
        verifyNever(repositoriesService.createStatus(any, any, any));
      });

      test('if status has not changed since last update', () async {
        final PullRequest pr = generatePullRequest(id: 1, sha: '1');
        when(pullRequestsService.list(any, base: anyNamed('base'))).thenAnswer((_) => Stream<PullRequest>.value(pr));
        buildStatusService.cumulativeStatus = BuildStatus.success();
        final GithubBuildStatusUpdate status = newStatusUpdate(pr, BuildStatus.success());
        db.values[status.key] = status;
        final Body body = await tester.get<Body>(handler);
        expect(body, same(Body.empty));
        expect(status.updates, 0);
      });

      test('if there is no pr found for a targeted branch', () async {
        final PullRequest pr = generatePullRequest(id: 1, sha: '1');
        when(pullRequestsService.list(any, base: anyNamed('base'))).thenAnswer((_) => Stream<PullRequest>.value(pr));
        buildStatusService.cumulativeStatus = BuildStatus.success();
        final GithubBuildStatusUpdate status =
            newStatusUpdate(pr, BuildStatus.failure(const <String>['failed_task_1']));
        db.values[status.key] = status;
        final Body body = await tester.get<Body>(handler);
        expect(body, same(Body.empty));
        expect(status.updates, 0);
        expect(status.status, BuildStatus.failure().githubStatus);
      });
    });

    test('updates github and datastore if status has changed since last update', () async {
      final PullRequest pr = generatePullRequest(id: 1, sha: '1');
      when(pullRequestsService.list(any, base: anyNamed('base'))).thenAnswer((_) => Stream<PullRequest>.value(pr));
      buildStatusService.cumulativeStatus = BuildStatus.success();
      final GithubBuildStatusUpdate status = newStatusUpdate(pr, BuildStatus.failure(const <String>['failed_test_1']));
      db.values[status.key] = status;
      final Body body = await tester.get<Body>(handler);
      expect(body, same(Body.empty));
      expect(status.updates, 1);
      expect(status.updateTimeMillis, isNotNull);
      expect(status.status, BuildStatus.success().githubStatus);
    });
  });
}
