// 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:buildbucket/buildbucket_pb.dart' as bbv2;
import 'package:cocoon_service/cocoon_service.dart';
import 'package:fixnum/fixnum.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../src/datastore/fake_config.dart';
import '../src/request_handling/fake_authentication.dart';
import '../src/request_handling/fake_http.dart';
import '../src/request_handling/subscription_tester.dart';
import '../src/service/fake_luci_build_service.dart';
import '../src/service/fake_scheduler.dart';
import '../src/utilities/build_bucket_messages.dart';
import '../src/utilities/mocks.dart';

const String ref = 'deadbeef';

void main() {
  late PresubmitLuciSubscription handler;
  late FakeConfig config;
  late MockGitHub mockGitHubClient;
  late FakeHttpRequest request;
  late SubscriptionTester tester;
  late MockRepositoriesService mockRepositoriesService;
  late MockGithubChecksService mockGithubChecksService;
  late MockLuciBuildService mockLuciBuildService;
  late FakeScheduler scheduler;

  setUp(() async {
    config = FakeConfig();
    mockLuciBuildService = MockLuciBuildService();

    mockGithubChecksService = MockGithubChecksService();
    scheduler = FakeScheduler(
      ciYaml: examplePresubmitRescheduleConfig,
      config: config,
      luciBuildService: mockLuciBuildService,
    );

    handler = PresubmitLuciSubscription(
      cache: CacheService(inMemory: true),
      config: config,
      luciBuildService: FakeLuciBuildService(config: config),
      githubChecksService: mockGithubChecksService,
      authProvider: FakeAuthenticationProvider(),
      scheduler: scheduler,
    );
    request = FakeHttpRequest();

    tester = SubscriptionTester(
      request: request,
    );

    mockGitHubClient = MockGitHub();
    mockRepositoriesService = MockRepositoriesService();
    when(mockGitHubClient.repositories).thenReturn(mockRepositoriesService);
    config.githubClient = mockGitHubClient;
  });

  test('Requests without repo_owner and repo_name do not update checks', () async {
    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux Host Engine',
      addBuildSet: false,
    );

    await tester.post(handler);

    verifyNever(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
      ),
    );
  });

  test('Requests with repo_owner and repo_name update checks', () async {
    when(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
      ),
    ).thenAnswer((_) async => true);

    when(mockGithubChecksService.taskFailed(any)).thenAnswer((_) => false);

    const Map<String, dynamic> userDataMap = {
      'repo_owner': 'flutter',
      'repo_name': 'cocoon',
    };

    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux Host Engine',
      userData: userDataMap,
    );

    await tester.post(handler);
    verify(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
      ),
    ).called(1);
  });

  test('Requests when task failed but no need to reschedule', () async {
    when(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
      ),
    ).thenAnswer((_) async => true);
    when(mockGithubChecksService.taskFailed(any)).thenAnswer((_) => true);
    when(mockGithubChecksService.currentAttempt(any)).thenAnswer((_) => 1);

    const Map<String, dynamic> userDataMap = {
      'repo_owner': 'flutter',
      'commit_branch': 'main',
      'commit_sha': 'abc',
      'repo_name': 'flutter',
    };

    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux A',
      userData: userDataMap,
    );

    final bbv2.BuildsV2PubSub buildsPubSub = createBuild(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux A',
    );

    when(
      mockLuciBuildService.rescheduleBuild(
        build: buildsPubSub.build,
        builderName: 'Linux Coverage',
        rescheduleAttempt: 0,
        userDataMap: userDataMap,
      ),
    ).thenAnswer(
      (_) async => bbv2.Build(
        id: Int64(8905920700440101120),
        builder: bbv2.BuilderID(bucket: 'luci.flutter.prod', project: 'flutter', builder: 'Linux Coverage'),
      ),
    );

    await tester.post(handler);
    verifyNever(
      mockLuciBuildService.rescheduleBuild(
        build: buildsPubSub.build,
        builderName: 'Linux Coverage',
        rescheduleAttempt: 0,
        userDataMap: userDataMap,
      ),
    );
    verify(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
      ),
    ).called(1);
  });

  test('Requests when task failed but need to reschedule', () async {
    when(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: true,
      ),
    ).thenAnswer((_) async => true);
    when(mockGithubChecksService.taskFailed(any)).thenAnswer((_) => true);
    when(mockGithubChecksService.currentAttempt(any)).thenAnswer((_) => 0);

    const Map<String, dynamic> userDataMap = {
      'repo_owner': 'flutter',
      'commit_branch': 'main',
      'commit_sha': 'abc',
      'repo_name': 'flutter',
    };

    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux B',
      userData: userDataMap,
    );

    final bbv2.BuildsV2PubSub buildsPubSub = createBuild(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux A',
    );

    when(
      mockLuciBuildService.rescheduleBuild(
        build: buildsPubSub.build,
        builderName: 'Linux Coverage',
        rescheduleAttempt: 1,
        userDataMap: userDataMap,
      ),
    ).thenAnswer(
      (_) async => bbv2.Build(
        id: Int64(8905920700440101120),
        builder: bbv2.BuilderID(bucket: 'luci.flutter.prod', project: 'flutter', builder: 'Linux B'),
      ),
    );
    await tester.post(handler);
    verifyNever(
      mockLuciBuildService.rescheduleBuild(
        build: buildsPubSub.build,
        builderName: 'Linux Coverage',
        rescheduleAttempt: 1,
        userDataMap: userDataMap,
      ),
    );
    verify(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: true,
      ),
    ).called(1);
  });

  test('Build not rescheduled if not found in ciYaml list.', () async {
    when(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: false,
      ),
    ).thenAnswer((_) async => true);
    when(mockGithubChecksService.taskFailed(any)).thenAnswer((_) => true);
    when(mockGithubChecksService.currentAttempt(any)).thenAnswer((_) => 1);

    const Map<String, dynamic> userDataMap = {
      'repo_owner': 'flutter',
      'commit_branch': 'main',
      'commit_sha': 'abc',
      'repo_name': 'flutter',
    };

    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux C',
      userData: userDataMap,
    );

    final bbv2.BuildsV2PubSub buildsPubSub = createBuild(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux C',
    );

    await tester.post(handler);
    verifyNever(
      mockLuciBuildService.rescheduleBuild(
        build: buildsPubSub.build,
        builderName: 'Linux C',
        userDataMap: userDataMap,
        rescheduleAttempt: 1,
      ),
    );
    verify(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: false,
      ),
    ).called(1);
  });

  test('Build not rescheduled if ci.yaml fails validation.', () async {
    scheduler.failCiYamlValidation = true;
    when(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: false,
      ),
    ).thenAnswer((_) async => true);
    when(mockGithubChecksService.taskFailed(any)).thenAnswer((_) => true);
    when(mockGithubChecksService.currentAttempt(any)).thenAnswer((_) => 1);

    final Map<String, dynamic> userDataMap = {
      'repo_owner': 'flutter',
      'commit_branch': Config.defaultBranch(Config.flutterSlug),
      'commit_sha': 'abc',
      'repo_name': 'flutter',
    };

    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux C',
      userData: userDataMap,
    );

    final bbv2.BuildsV2PubSub buildsPubSub = createBuild(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux C',
    );

    await tester.post(handler);
    verifyNever(
      mockLuciBuildService.rescheduleBuild(
        build: buildsPubSub.build,
        builderName: 'Linux C',
        userDataMap: userDataMap,
        rescheduleAttempt: 1,
      ),
    );
    verify(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: false,
      ),
    ).called(1);
  });

  test('Build contains data from build_large_fields', () async {
    when(
      mockGithubChecksService.updateCheckStatus(
        build: anyNamed('build'),
        userDataMap: anyNamed('userDataMap'),
        luciBuildService: anyNamed('luciBuildService'),
        slug: anyNamed('slug'),
        rescheduled: anyNamed('rescheduled'),
      ),
    ).thenAnswer((_) async => true);
    when(mockGithubChecksService.taskFailed(any)).thenAnswer((_) => true);
    when(mockGithubChecksService.currentAttempt(any)).thenAnswer((_) => 0);

    const Map<String, dynamic> userDataMap = {
      'repo_owner': 'flutter',
      'commit_branch': 'main',
      'commit_sha': 'abc',
      'repo_name': 'flutter',
    };

    tester.message = createPushMessage(
      Int64(1),
      status: bbv2.Status.SUCCESS,
      builder: 'Linux A',
      userData: userDataMap,
    );

    when(
      mockLuciBuildService.rescheduleBuild(
        build: captureAnyNamed('build'),
        builderName: anyNamed('builderName'),
        rescheduleAttempt: anyNamed('rescheduleAttempt'),
        userDataMap: anyNamed('userDataMap'),
      ),
    ).thenAnswer((_) async {
      return bbv2.Build(
        id: Int64(8905920700440101120),
        builder: bbv2.BuilderID(bucket: 'luci.flutter.prod', project: 'flutter', builder: 'Linux Coverage'),
      );
    });

    /// Create a handler using the mock LuciBuildService instead of the fake.
    final PresubmitLuciSubscription luciHandler = PresubmitLuciSubscription(
      cache: CacheService(inMemory: true),
      config: config,
      luciBuildService: mockLuciBuildService,
      githubChecksService: mockGithubChecksService,
      authProvider: FakeAuthenticationProvider(),
      scheduler: scheduler,
    );

    await tester.post(luciHandler);

    final bbv2.Build build = verify(
      mockLuciBuildService.rescheduleBuild(
        build: captureAnyNamed('build'),
        builderName: anyNamed('builderName'),
        rescheduleAttempt: anyNamed('rescheduleAttempt'),
        userDataMap: anyNamed('userDataMap'),
      ),
    ).captured[0];

    // Check that the build.input.properties extracted from build_large_fields
    // contains the git_ref property encoded in the test data.
    expect(build.input.properties.fields, contains('git_ref'));
  });
}
