package ru.dbotthepony.mc.otm.capability.matter

import java.util.*
import java.util.stream.Stream

interface IReplicationTaskProvider {
	/**
	 * It must return new stream each time
	 */
	val replicationTasks: Stream<out IReplicationTask<*>>

	/**
	 * It must return new stream each time
	 */
	val allReplicationTasks: Stream<out IReplicationTask<*>>

	/**
	 * Allocates (marks as work-in-progress) a task
	 * by incrementing it's [IReplicationTask.inProgress] by 1
	 * and shrinking [IReplicationTask.required] by 1
	 *
	 * If [IReplicationTask.required] == 0, it should not be returned by this method
	 * @param simulate whenever to change internal state
	 * @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available
	 */
	fun allocateTask(simulate: Boolean): ReplicationTaskAllocation?

	/**
	 * Notify about task completion. If this provider indeed contain this task, it should
	 * shrink in_progress by 1
	 * If in_progress == 0 and required == 0, it should discard the task
	 * @param taskId task being completed. this method should ignore tasks that are not owned by it.
	 * @return whenever task indeed belong to this provider and internal state was updated
	 */
	fun notifyTaskCompletion(taskId: UUID): Boolean

	/**
	 * @param id uuid of task
	 * @return MatterTask that this capability holds with this id, or null
	 */
	fun getTask(id: UUID): IReplicationTask<*>? {
		return allReplicationTasks.filter { it.id == id }.findAny().orElse(null)
	}

	/**
	 * Destroys all tasks this capability contains
	 */
	fun dropAllTasks()
}