// 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:appengine/appengine.dart';
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/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:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../src/bigquery/fake_tabledata_resource.dart';
import '../src/datastore/fake_cocoon_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/request_handling/fake_http.dart';
import '../src/request_handling/fake_logging.dart';
import '../src/service/fake_build_status_provider.dart';
import '../src/service/fake_github_service.dart';
import '../src/utilities/mocks.dart';

void main() {
  group('PushBuildStatusToGithub', () {
    FakeConfig config;
    FakeClientContext clientContext;
    FakeAuthenticatedContext authContext;
    FakeAuthenticationProvider auth;
    FakeDatastoreDB db;
    FakeLogging log;
    FakeBuildStatusService buildStatusService;
    ApiRequestHandlerTester tester;
    PushBuildStatusToGithub handler;
    FakeTabledataResourceApi tabledataResourceApi;
    FakeHttpClient branchHttpClient;
    List<int> githubPullRequestsMaster;
    List<int> githubPullRequestsOther;
    MockRepositoriesService repositoriesService;

    List<PullRequest> pullRequestList(String branch) {
      final List<PullRequest> pullRequests = <PullRequest>[];
      for (int pr in (branch == 'master')
          ? githubPullRequestsMaster
          : githubPullRequestsOther) {
        pullRequests.add(PullRequest()
          ..number = pr
          ..head = (PullRequestHead()..sha = pr.toString()));
      }
      return pullRequests;
    }

    setUp(() {
      clientContext = FakeClientContext();
      authContext = FakeAuthenticatedContext(clientContext: clientContext);
      auth = FakeAuthenticationProvider(clientContext: clientContext);
      buildStatusService = FakeBuildStatusService();
      tabledataResourceApi = FakeTabledataResourceApi();
      branchHttpClient = FakeHttpClient();
      final FakeGithubService githubService = FakeGithubService();
      db = FakeDatastoreDB();
      config = FakeConfig(
          tabledataResourceApi: tabledataResourceApi,
          githubService: githubService,
          dbValue: db);
      log = FakeLogging();
      tester = ApiRequestHandlerTester(context: authContext);
      handler = PushBuildStatusToGithub(
        config,
        auth,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        loggingProvider: () => log,
        buildStatusServiceProvider: (_) => buildStatusService,
        branchHttpClientProvider: () => branchHttpClient,
        gitHubBackoffCalculator: (int attempt) => Duration.zero,
      );

      githubPullRequestsMaster = <int>[];
      githubPullRequestsOther = <int>[];
      githubService.listPullRequestsBranch = (String branch) {
        return pullRequestList(branch);
      };

      repositoriesService = MockRepositoriesService();
      when(githubService.github.repositories).thenReturn(repositoriesService);
    });

    group('in development environment', () {
      setUp(() {
        clientContext.isDevelopmentEnvironment = true;
      });

      test('Does nothing', () async {
        config.githubClient = ThrowingGitHub();
        db.onCommit =
            (List<gcloud_db.Model> insert, List<gcloud_db.Key> 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('in non-development environment', () {
      setUp(() {
        clientContext.isDevelopmentEnvironment = false;
      });

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

      PullRequest newPullRequest({@required int id, @required String sha}) {
        return PullRequest()
          ..number = id
          ..head = (PullRequestHead()..sha = sha);
      }

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

        test('if there are no PRs', () async {
          config.flutterBranchesValue = <String>['master'];
          buildStatusService.cumulativeStatus = BuildStatus.succeeded;
          final Body body = await tester.get<Body>(handler);
          final TableDataList tableDataList =
              await tabledataResourceApi.list('test', 'test', 'test');
          expect(body, same(Body.empty));
          expect(log.records.where(hasLevel(LogLevel.WARNING)), isEmpty);
          expect(log.records.where(hasLevel(LogLevel.ERROR)), isEmpty);

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

        test('if status has not changed since last update', () async {
          githubPullRequestsMaster = <int>[1];
          final PullRequest pr = newPullRequest(id: 1, sha: '1');
          config.flutterBranchesValue = <String>['master'];
          buildStatusService.cumulativeStatus = BuildStatus.succeeded;
          final GithubBuildStatusUpdate status =
              newStatusUpdate(pr, BuildStatus.succeeded);
          db.values[status.key] = status;
          final Body body = await tester.get<Body>(handler);
          expect(body, same(Body.empty));
          expect(status.updates, 0);
          expect(log.records.where(hasLevel(LogLevel.WARNING)), isEmpty);
          expect(log.records.where(hasLevel(LogLevel.ERROR)), isEmpty);
        });

        test('if there is no pr found for a targeted branch', () async {
          githubPullRequestsMaster = <int>[1];
          final PullRequest pr = newPullRequest(id: 1, sha: '1');
          config.flutterBranchesValue = <String>['flutter-0.0-candidate.0'];
          buildStatusService.cumulativeStatus = BuildStatus.succeeded;
          final GithubBuildStatusUpdate status =
              newStatusUpdate(pr, BuildStatus.failed);
          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.failed.githubStatus);
          expect(log.records.where(hasLevel(LogLevel.WARNING)), isEmpty);
          expect(log.records.where(hasLevel(LogLevel.ERROR)), isEmpty);
        });
      });

      group('updates GitHub and datastore', () {
        test('if status has changed since last update', () async {
          githubPullRequestsOther = <int>[1];
          final PullRequest pr = newPullRequest(id: 1, sha: '1');
          config.flutterBranchesValue = <String>['flutter-0.0-candidate.0'];
          buildStatusService.cumulativeStatus = BuildStatus.succeeded;
          final GithubBuildStatusUpdate status =
              newStatusUpdate(pr, BuildStatus.failed);
          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.succeeded.githubStatus);
          expect(log.records.where(hasLevel(LogLevel.WARNING)), isEmpty);
          expect(log.records.where(hasLevel(LogLevel.ERROR)), isEmpty);
        });

        test(
            'update if statuses have changed since last update - multiple branches',
            () async {
          githubPullRequestsMaster = <int>[123];
          githubPullRequestsOther = <int>[456];
          final PullRequest prMaster = newPullRequest(id: 123, sha: '123');
          final PullRequest prOther = newPullRequest(id: 456, sha: '456');
          config.flutterBranchesValue = <String>[
            'flutter-0.0-candidate.0',
            'master'
          ];
          buildStatusService.cumulativeStatus = BuildStatus.succeeded;
          final GithubBuildStatusUpdate statusOther =
              newStatusUpdate(prOther, BuildStatus.failed);
          db.values[statusOther.key] = statusOther;
          final GithubBuildStatusUpdate statusMaster =
              newStatusUpdate(prMaster, BuildStatus.failed);
          db.values[statusMaster.key] = statusMaster;
          final Body body = await tester.get<Body>(handler);
          expect(body, same(Body.empty));
          expect(statusMaster.updates, 1);
          expect(statusOther.updates, 1);
          expect(statusMaster.status, BuildStatus.succeeded.githubStatus);
          expect(statusOther.status, BuildStatus.succeeded.githubStatus);
          expect(log.records.where(hasLevel(LogLevel.WARNING)), isEmpty);
          expect(log.records.where(hasLevel(LogLevel.ERROR)), isEmpty);
        });
      });
    });
  });
}
