import { assert } from "../../../assert.js";
import Task from "../Task.js";
import { TaskSignal } from "../TaskSignal.js";

/**
 * Produces a new task that wraps input, will execute input task but if input task fails - this wrapper task will still resolve in success
 * @param {Task} task
 * @returns {Task}
 */
export function ignoreFailureTask(task) {
    assert.defined(task, 'task');
    assert.isObject(task, 'task');
    assert.equal(task.isTask, true, 'task.isTask !== true');

    let initializationFailed = false;

    const wrapper = new Task({
        name: `Ignore Failure of [${task.name}]`,
        initializer(me, executor) {
            try {
                task.initialize(task, executor);
            } catch (e) {
                initializationFailed = true;
                console.warn(e);
            }
        },
        estimatedDuration: task.estimatedDuration,
        cycleFunction() {

            task.__executedCpuTime = wrapper.__executedCpuTime;
            task.__executedCycleCount = wrapper.__executedCycleCount;

            if (initializationFailed) {
                //initializer failed, don't execute the source task
                return TaskSignal.EndSuccess;
            }

            const c = task.cycle();

            if (c === TaskSignal.EndFailure) {
                return TaskSignal.EndSuccess;
            }

            return c;
        },
        computeProgress() {
            return task.computeProgress();
        }
    });

    return wrapper;
}
