// 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/luci/push_message.dart';
import 'package:cocoon_service/src/service/luci.dart';
import 'package:gcloud/db.dart';
import 'package:test/test.dart';

import '../src/utilities/entity_generators.dart';

void main() {
  group('Task', () {
    test('byAttempts comparator', () {
      final List<Task> tasks = <Task>[
        generateTask(1, attempts: 5),
        generateTask(2, attempts: 9),
        generateTask(3, attempts: 3),
      ];
      tasks.sort(Task.byAttempts);
      expect(tasks.map<int>((Task task) => task.attempts!), <int>[3, 5, 9]);
    });

    test('disallows illegal status', () {
      expect(() => generateTask(1, status: 'unknown'), throwsArgumentError);
      expect(() => generateTask(1)..status = 'unknown', throwsArgumentError);
    });

    test('creates a valid chromebot task', () {
      final Key<String> commitKey = generateKey<String>(Commit, 'flutter/flutter/master/42');
      const LuciBuilder builder = LuciBuilder(
        name: 'builderAbc',
        repo: 'flutter/flutter',
        taskName: 'taskName',
        flaky: false,
      );
      final Task task = Task.chromebot(commitKey: commitKey, createTimestamp: 123, builder: builder);
      validateModel(task);
      expect(task.name, 'taskName');
      expect(task.builderName, 'builderAbc');
      expect(task.createTimestamp, 123);
      expect(task.isFlaky, false);
      expect(task.requiredCapabilities, <String>['can-update-github']);
      expect(task.timeoutInMinutes, 0);
    });

    test('flaky defaults to false', () {
      final Key<String> commitKey = generateKey<String>(Commit, 'flutter/flutter/master/42');
      const LuciBuilder builder = LuciBuilder(
        name: 'builderAbc',
        repo: 'flutter/flutter',
        taskName: 'taskName',
        flaky: null,
      );
      expect(Task.chromebot(commitKey: commitKey, createTimestamp: 123, builder: builder).isFlaky, isFalse);
    });

    group('updateFromBuild', () {
      test('updates if buildNumber is null', () {
        final DateTime created = DateTime.utc(2022, 1, 11, 1, 1);
        final DateTime started = DateTime.utc(2022, 1, 11, 1, 2);
        final DateTime completed = DateTime.utc(2022, 1, 11, 1, 3);
        final Build build = generatePushMessageBuild(
          1,
          createdTimestamp: created,
          startedTimestamp: started,
          completedTimestamp: completed,
        );
        final Task task = generateTask(1);

        expect(task.status, Task.statusNew);
        expect(task.buildNumberList, isNull);
        expect(task.buildNumber, isNull);
        expect(task.endTimestamp, 0);
        expect(task.createTimestamp, 0);
        expect(task.startTimestamp, 0);

        task.updateFromBuild(build);

        expect(task.status, Task.statusSucceeded);
        expect(task.buildNumber, 1);
        expect(task.buildNumberList, '1');
        expect(task.createTimestamp, created.millisecondsSinceEpoch);
        expect(task.startTimestamp, started.millisecondsSinceEpoch);
        expect(task.endTimestamp, completed.millisecondsSinceEpoch);
      });

      test('defaults timestamps to 0', () {
        final Build build = generatePushMessageBuild(1);
        final Task task = generateTask(1);

        expect(task.endTimestamp, 0);
        expect(task.createTimestamp, 0);
        expect(task.startTimestamp, 0);

        task.updateFromBuild(build);

        expect(task.endTimestamp, 0);
        expect(task.createTimestamp, 0);
        expect(task.startTimestamp, 0);
      });

      test('updates if buildNumber is prior to pushMessage', () {
        final Build build = generatePushMessageBuild(
          1,
          buildNumber: 2,
          status: Status.started,
        );
        final Task task = generateTask(
          1,
          buildNumber: 1,
          status: Task.statusSucceeded,
        );

        expect(task.buildNumberList, '1');
        expect(task.status, Task.statusSucceeded);

        task.updateFromBuild(build);

        expect(task.buildNumber, 2);
        expect(task.buildNumberList, '1,2');
        expect(task.status, Task.statusInProgress);
      });

      test('does not duplicate build numbers on multiple messages', () {
        final Build build = generatePushMessageBuild(
          1,
          status: Status.started,
        );
        final Task task = generateTask(
          1,
          buildNumber: 1,
          status: Task.statusSucceeded,
        );

        expect(task.buildNumber, 1);
        expect(task.buildNumberList, '1');
        expect(task.status, Task.statusSucceeded);

        task.updateFromBuild(build);

        expect(task.buildNumber, 1);
        expect(task.buildNumberList, '1');
        expect(task.status, Task.statusSucceeded);
      });

      test('does not update status if older status', () {
        final Build build = generatePushMessageBuild(
          1,
          status: Status.started,
        );
        final Task task = generateTask(
          1,
          buildNumber: 1,
          status: Task.statusSucceeded,
        );

        expect(task.buildNumber, 1);
        expect(task.status, Task.statusSucceeded);

        task.updateFromBuild(build);

        expect(task.buildNumber, 1);
        expect(task.status, Task.statusSucceeded);
      });

      test('does not update if build is older than task', () {
        final Build build = generatePushMessageBuild(
          1,
          status: Status.completed,
          result: Result.success,
        );
        final Task task = generateTask(
          1,
          buildNumber: 2,
          status: Task.statusNew,
        );

        expect(task.buildNumber, 2);
        expect(task.status, Task.statusNew);

        task.updateFromBuild(build);

        expect(task.buildNumber, 2);
        expect(task.status, Task.statusNew);
      });

      test('handles cancelled build', () {
        final Build build = generatePushMessageBuild(
          1,
          status: Status.completed,
          result: Result.canceled,
        );
        final Task task = generateTask(
          1,
          buildNumber: 1,
          status: Task.statusNew,
        );

        expect(task.status, Task.statusNew);
        task.updateFromBuild(build);
        expect(task.status, Task.statusCancelled);
      });
    });
  });
}

void validateModel(Task task) {
  // Throws an exception when property validation fails.
  ModelDBImpl().toDatastoreEntity(task);
}
