// Copyright 2021 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/service/datastore.dart';

import '../../model/appengine/task.dart';
import '../logging.dart';
import '../luci_build_service.dart';

/// Interface for implementing various scheduling policies in the Cocoon scheduler.
abstract class SchedulerPolicy {
  /// Returns the priority of [Task].
  ///
  /// If null is returned, the task should not be scheduled.
  Future<int?> triggerPriority({
    required Task task,
    required DatastoreService datastore,
  });
}

/// Every [Task] is triggered to run.
class GuaranteedPolicy implements SchedulerPolicy {
  @override
  Future<int?> triggerPriority({
    required Task task,
    required DatastoreService datastore,
  }) async {
    final List<Task> recentTasks = await datastore.queryRecentTasksByName(name: task.name!).toList();
    // Ensure task isn't considered in recentTasks
    recentTasks.removeWhere((Task t) => t.commitKey == task.commitKey);
    if (recentTasks.isEmpty) {
      log.warning('${task.name} is newly added, triggerring builds regardless of policy');
      return LuciBuildService.kDefaultPriority;
    }
    // Prioritize tasks that recently failed.
    if (shouldRerunPriority(recentTasks, 1)) {
      return LuciBuildService.kRerunPriority;
    }
    return LuciBuildService.kDefaultPriority;
  }
}

/// [Task] is run at least every 6 commits.
///
/// If there is capacity, a backfiller cron triggers the latest task that was not run
/// to ensure ToT is always tested.
///
/// This is intended for targets that are run in an infra pool that has limited capacity,
/// such as the on device tests in the DeviceLab.
class BatchPolicy implements SchedulerPolicy {
  static const int kBatchSize = 6;
  @override
  Future<int?> triggerPriority({
    required Task task,
    required DatastoreService datastore,
  }) async {
    final List<Task> recentTasks = await datastore.queryRecentTasksByName(name: task.name!).toList();
    // Ensure task isn't considered in recentTasks
    recentTasks.removeWhere((Task t) => t.commitKey == task.commitKey);
    if (recentTasks.length < kBatchSize) {
      log.warning('${task.name} has less than $kBatchSize, triggerring all builds regardless of policy');
      return LuciBuildService.kDefaultPriority;
    }

    // Prioritize tasks that recently failed.
    if (shouldRerunPriority(recentTasks, kBatchSize)) {
      return LuciBuildService.kRerunPriority;
    }

    if (allNew(recentTasks.sublist(0, kBatchSize - 1))) {
      return LuciBuildService.kDefaultPriority;
    }

    return null;
  }
}

/// Checks if all tasks are with [Task.statusNew].
bool allNew(List<Task> tasks) {
  for (Task task in tasks) {
    if (task.status != Task.statusNew) {
      return false;
    }
  }
  return true;
}

/// Return true if there is an earlier failed build.
bool shouldRerunPriority(List<Task> tasks, int pastTaskNumber) {
  // Prioritize tasks that recently failed.
  bool hasRecentFailure = false;
  for (int i = 0; i < pastTaskNumber && i < tasks.length; i++) {
    if (_isFailed(tasks[i])) {
      hasRecentFailure = true;
      break;
    }
  }
  return hasRecentFailure;
}

bool _isFailed(Task task) {
  return task.status == Task.statusFailed || task.status == Task.statusInfraFailure;
}

/// [Task] run outside of Cocoon are not triggered by the Cocoon scheduler.
class OmitPolicy implements SchedulerPolicy {
  @override
  Future<int?> triggerPriority({
    required Task task,
    required DatastoreService datastore,
  }) async =>
      null;
}
