"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Scheduler = void 0;
const logger_1 = require("@refloat/logger");
const run_env_1 = require("./run-env");
const task_1 = require("./task");
const logger = logger_1.Logger.create('scheduler');
class Scheduler {
    constructor(queue) {
        this.queue = queue;
    }
    async run(graph) {
        const tasks = new task_1.Tasks(graph);
        const env = new run_env_1.RunEnv(graph, this.queue.api);
        await env.init();
        try {
            while (!tasks.done()) {
                for (const task of tasks.queue(graph)) {
                    const start = Date.now();
                    task.state = task_1.TaskState.Running;
                    logger.info('running', { step: task.node.step.path });
                    tasks.run(async () => {
                        this.queue.start(task.node.step.id);
                        const code = await this.exec(task, env);
                        const success = code === 0;
                        this.queue.complete(task.node.step.id, success);
                        task.state = success ? task_1.TaskState.Done : task_1.TaskState.Failed;
                        logger.info(success ? 'completed' : 'failed', {
                            step: task.node.step.path,
                            duration: `${Date.now() - start}ms`,
                        });
                    });
                }
                logger.debug('waiting for steps to run');
                await tasks.wait();
            }
            return tasks.state();
        }
        finally {
            await env.clean();
        }
    }
    async exec(task, env) {
        try {
            return await env.exec(task.node, (chunk) => this.queue.progress(task.node.step.id, chunk));
        }
        catch (error) {
            return null;
        }
    }
}
exports.Scheduler = Scheduler;
//# sourceMappingURL=scheduler.js.map