// 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/model/appengine/task.dart';
import 'package:cocoon_service/src/model/ci_yaml/target.dart';
import 'package:cocoon_service/src/request_handlers/refresh_chromebot_status.dart';
import 'package:cocoon_service/src/service/config.dart';
import 'package:cocoon_service/src/service/datastore.dart';
import 'package:cocoon_service/src/service/luci.dart';
import 'package:gcloud/db.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 '../src/bigquery/fake_tabledata_resource.dart';
import '../src/datastore/fake_config.dart';
import '../src/request_handling/api_request_handler_tester.dart';
import '../src/request_handling/fake_authentication.dart';
import '../src/service/fake_scheduler.dart';
import '../src/utilities/mocks.dart';

void main() {
  group('RefreshChromebotStatus', () {
    late FakeConfig config;
    late ApiRequestHandlerTester tester;
    late MockLuciService mockLuciService;
    late RefreshChromebotStatus handler;
    late MockClient branchHttpClient;
    late FakeScheduler scheduler;
    late FakeTabledataResource tabledataResource;
    late MockLuciBuildService mockLuciBuildService;

    late Commit commit;
    late List<LuciBuilder> builders;

    setUp(() async {
      tabledataResource = FakeTabledataResource();
      config = FakeConfig(tabledataResource: tabledataResource);
      config.flutterBranchesValue = <String>[Config.defaultBranch(Config.flutterSlug)];
      tester = ApiRequestHandlerTester();
      mockLuciService = MockLuciService();
      mockLuciBuildService = MockLuciBuildService();
      branchHttpClient = MockClient((_) async => http.Response('', 200));
      scheduler = FakeScheduler(
        config: config,
        ciYaml: exampleConfig,
      );
      handler = RefreshChromebotStatus(
        config,
        FakeAuthenticationProvider(),
        mockLuciBuildService,
        luciServiceProvider: (_) => mockLuciService,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        branchHttpClientProvider: () => branchHttpClient,
        gitHubBackoffCalculator: (int attempt) => Duration.zero,
        scheduler: scheduler,
      );
      commit = Commit(
        key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/master/abc'),
        sha: 'abc',
        branch: Config.defaultBranch(Config.flutterSlug),
        repository: Config.flutterSlug.fullName,
      );
      builders = await scheduler.getPostSubmitBuilders(exampleConfig);
    });

    group('without builder rerun', () {
      setUp(() {
        when(mockLuciBuildService.checkRerunBuilder(
          commit: anyNamed('commit'),
          target: anyNamed('target'),
          task: anyNamed('task'),
          datastore: anyNamed('datastore'),
          ignoreChecks: false,
        )).thenAnswer((_) => Future<bool>.value(false));
      });

      test('do not update task status when SHA does not match', () async {
        final Task task = Task(
          key: commit.key.append(Task, id: 123),
          commitKey: commit.key,
          name: 'Linux A',
          status: Task.statusNew,
        );
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;

        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'def': <LuciTask>[
                const LuciTask(
                    commitSha: 'def',
                    ref: 'refs/heads/master',
                    status: Task.statusSucceeded,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusNew);
      });

      test('do not update task status when commitSha/ref is unknown', () async {
        final Task task = Task(
          key: commit.key.append(Task, id: 123),
          commitKey: commit.key,
          name: 'Linux A',
          status: Task.statusNew,
        );
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;

        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'def': <LuciTask>[
                const LuciTask(
                    commitSha: 'unknown',
                    ref: 'unknown',
                    status: Task.statusSucceeded,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusNew);
      });

      test('do not update task status when branch does not match', () async {
        final Commit branchCommit = Commit(
          key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/test/abc'),
          sha: 'abc',
          branch: 'test',
          repository: Config.flutterSlug.fullName,
        );
        final Task task = Task(
          key: branchCommit.key.append(Task, id: 123),
          commitKey: branchCommit.key,
          name: 'Linux A',
          status: Task.statusNew,
        );
        config.db.values[branchCommit.key] = branchCommit;
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusSucceeded,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusNew);
      });

      test('update task status and buildNumber when buildNumberList does not match', () async {
        final Task task =
            Task(key: commit.key.append(Task, id: 123), commitKey: commit.key, name: 'Linux A', status: Task.statusNew);
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusSucceeded,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        expect(task.buildNumberList, isNull);
        await tester.get(handler);
        expect(task.status, Task.statusSucceeded);
        expect(task.buildNumberList, '1');
      });

      test('save data to BigQuery when task finishes', () async {
        final Task task =
            Task(key: commit.key.append(Task, id: 123), commitKey: commit.key, name: 'Linux A', status: Task.statusNew);
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusSucceeded,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        await tester.get(handler);
        final TableDataList tableDataList = await tabledataResource.list('test', 'test', 'test');
        expect(tableDataList.totalRows, '1');
      });

      test('update task status and buildNumber when status does not match', () async {
        final Task task = Task(
            key: commit.key.append(Task, id: 123),
            commitKey: commit.key,
            name: 'Linux A',
            status: Task.statusNew,
            buildNumberList: '1');
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusSucceeded,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusSucceeded);
      });

      test('update task status with latest status when multilple reruns exist', () async {
        final Task task = Task(
            key: commit.key.append(Task, id: 123),
            commitKey: commit.key,
            name: 'Linux A',
            status: Task.statusNew,
            buildNumberList: '1');
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusSucceeded,
                    buildNumber: 2,
                    builderName: 'abc'),
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusFailed,
                    buildNumber: 1,
                    builderName: 'abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusSucceeded);
        expect(task.buildNumberList, '1,2');
      });

      test('update task status with latest status when ci yaml targets exist', () async {
        final Task task = Task(
            key: commit.key.append(Task, id: 123),
            commitKey: commit.key,
            name: 'Linux A',
            builderName: 'Linux A',
            status: Task.statusNew,
            buildNumberList: '1');
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        scheduler.ciYaml = exampleConfig;
        final List<LuciBuilder> builders =
            scheduler.ciYaml!.postsubmitTargets.map((Target target) => LuciBuilder.fromTarget(target)).toList();
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                  commitSha: 'abc',
                  ref: 'refs/heads/master',
                  status: Task.statusSucceeded,
                  buildNumber: 2,
                  builderName: 'Linux A',
                ),
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusSucceeded);
        expect(task.buildNumberList, '2');
      });

      test('update task status for non master branch', () async {
        final Commit branchCommit = Commit(
          key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/test/def'),
          sha: 'def',
          branch: 'test',
          repository: Config.flutterSlug.fullName,
        );
        final Task task = Task(
            key: branchCommit.key.append(Task, id: 456),
            commitKey: branchCommit.key,
            name: 'Linux A',
            status: Task.statusNew);
        config.flutterBranchesValue = <String>[Config.defaultBranch(Config.flutterSlug), 'test'];
        config.db.values[commit.key] = commit;
        config.db.values[branchCommit.key] = branchCommit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'def': <LuciTask>[
                const LuciTask(
                    commitSha: 'def',
                    ref: 'refs/heads/master',
                    status: Task.statusFailed,
                    buildNumber: 1,
                    builderName: 'abc'),
              ],
            }
        };
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> testLuciTasks = {
          for (LuciBuilder builder in builders)
            BranchLuciBuilder(luciBuilder: builder, branch: 'test'): <String, List<LuciTask>>{
              'def': <LuciTask>[
                const LuciTask(
                    commitSha: 'def',
                    ref: 'refs/heads/test',
                    status: Task.statusSucceeded,
                    buildNumber: 2,
                    builderName: 'abc')
              ],
            }
        };
        luciTasks.addAll(testLuciTasks);
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusNew);
        await tester.get(handler);
        expect(task.status, Task.statusSucceeded);
        expect(task.luciBucket, 'luci.flutter.prod');
      });
    });

    group('with builder rerun', () {
      setUp(() {
        when(mockLuciBuildService.checkRerunBuilder(
          commit: anyNamed('commit'),
          target: anyNamed('target'),
          task: anyNamed('task'),
          datastore: anyNamed('datastore'),
        )).thenAnswer((_) => Future<bool>.value(true));
      });

      test('rerun Mac builder when hiting recipe infra failure', () async {
        config.maxTaskRetriesValue = 2;
        final Task task = Task(
            key: commit.key.append(Task, id: 123),
            commitKey: commit.key,
            name: 'Linux A',
            status: Task.statusInProgress,
            buildNumberList: '1',
            attempts: 0,
            builderName: 'Mac abc');
        config.db.values[commit.key] = commit;
        config.db.values[task.key] = task;
        final Map<BranchLuciBuilder, Map<String, List<LuciTask>>> luciTasks = {
          for (LuciBuilder builder in <LuciBuilder>[
            LuciBuilder(name: 'Mac abc', repo: Config.flutterSlug.name, taskName: 'def', flaky: false)
          ])
            BranchLuciBuilder(luciBuilder: builder, branch: 'master'): <String, List<LuciTask>>{
              'abc': <LuciTask>[
                const LuciTask(
                    commitSha: 'abc',
                    ref: 'refs/heads/master',
                    status: Task.statusInfraFailure,
                    buildNumber: 1,
                    builderName: 'Mac abc')
              ],
            }
        };
        when(mockLuciService.getBranchRecentTasks(builders: anyNamed('builders'), requireTaskName: true))
            .thenAnswer((Invocation invocation) {
          return Future<Map<BranchLuciBuilder, Map<String, List<LuciTask>>>>.value(luciTasks);
        });

        expect(task.status, Task.statusInProgress);
        await tester.get(handler);
        verify(mockLuciBuildService.checkRerunBuilder(
                commit: anyNamed('commit'),
                target: anyNamed('target'),
                task: anyNamed('task'),
                datastore: anyNamed('datastore'),
                tags: anyNamed('tags'),
                ignoreChecks: false))
            .called(1);
      });
    });
  });
}
