"use strict";
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var storable_realtime_subscriptions_1 = __importDefault(require("../../Data/storable-realtime-subscriptions"));
var runs_consts_1 = require("../runs.consts");
var RunRealtimeSubscriptions = /** @class */ (function () {
    function RunRealtimeSubscriptions(session, runsStore, storableDataService) {
        var _this = this;
        this.runsStore = runsStore;
        this.storableDataService = storableDataService;
        this.updateTaskIdsOnDelete = function (task) {
            var existingRun = _this.runsStore.get(task.run_id);
            if (!existingRun) {
                return;
            }
            var updatedTaskIds = new Set(existingRun.task_ids);
            updatedTaskIds.delete(task.id);
            _this.updateRunInStore(existingRun, updatedTaskIds);
        };
        this.storableRealtimeSubscriptions = new storable_realtime_subscriptions_1.default(session, runsStore, storableDataService);
        this.taskIdsWaitingForRun = new Map();
    }
    RunRealtimeSubscriptions.prototype.updateStoreOnEvents = function (tasksApi) {
        var _this = this;
        var runExtractor = function (_a) {
            var run = _a.run;
            return run;
        };
        this.storableRealtimeSubscriptions.updateStoreOnEvents([
            {
                name: runs_consts_1.RunEvents.CREATED,
                isDelete: false,
                extraDataFunc: this.addTaskIdsOnCreateOrUpdate.bind(this),
                itemExtractor: runExtractor
            },
            {
                name: runs_consts_1.RunEvents.UPDATED,
                isDelete: false,
                extraDataFunc: this.addTaskIdsOnCreateOrUpdate.bind(this),
                itemExtractor: runExtractor
            },
            { name: runs_consts_1.RunEvents.DELETED, isDelete: true }
        ]);
        tasksApi.onCreate(function (item) {
            _this.updateTaskIds(item.current);
        });
        tasksApi.onUpdate(function (item) {
            _this.updateTaskIds(item.current);
        });
        tasksApi.onDelete(function (item) {
            _this.updateTaskIdsOnDelete(item.diff);
        });
    };
    RunRealtimeSubscriptions.prototype.onUpdate = function (callback) {
        return this.storableRealtimeSubscriptions.onEvent(runs_consts_1.RunEvents.UPDATED, callback);
    };
    RunRealtimeSubscriptions.prototype.onDelete = function (callback) {
        return this.storableRealtimeSubscriptions.onEvent(runs_consts_1.RunEvents.DELETED, callback);
    };
    RunRealtimeSubscriptions.prototype.onCreate = function (callback) {
        return this.storableRealtimeSubscriptions.onEvent(runs_consts_1.RunEvents.CREATED, callback);
    };
    RunRealtimeSubscriptions.prototype.addTaskIdsOnCreateOrUpdate = function (run) {
        if (run.task_ids || run.tasks) {
            return;
        }
        var existingRun = this.runsStore.get(run.id);
        var taskIdsWaitingForRun = this.taskIdsWaitingForRun.get(run.id) || new Set();
        var taskIds = existingRun
            ? Array.from(new Set(__spreadArray(__spreadArray([], __read(existingRun.task_ids), false), __read(taskIdsWaitingForRun), false)))
            : Array.from(taskIdsWaitingForRun);
        this.taskIdsWaitingForRun.delete(run.id);
        return { params: { taskIds: taskIds } };
    };
    RunRealtimeSubscriptions.prototype.updateTaskIds = function (task) {
        var existingRun = this.runsStore.getGroup(runs_consts_1.RunGroupTypes.TaskIds, task.id)[0];
        if (task.run_id) {
            var newRun = this.runsStore.get(task.run_id);
            if (!newRun) {
                this.backupTasksUntilRunIsCreated(task);
            }
            else if (this.taskAddedToRun(task, newRun)) {
                var updatedTaskIds = new Set(newRun.task_ids);
                updatedTaskIds.add(task.id);
                this.updateRunInStore(newRun, updatedTaskIds);
            }
        }
        else if (this.taskRemovedFromRun(task, existingRun)) {
            var updatedTaskIds = new Set(existingRun.task_ids);
            updatedTaskIds.delete(task.id);
            this.updateRunInStore(existingRun, updatedTaskIds);
        }
        this.updatePreviousRun(task, existingRun === null || existingRun === void 0 ? void 0 : existingRun.id);
    };
    RunRealtimeSubscriptions.prototype.updatePreviousRun = function (task, previousRunId) {
        if (previousRunId && previousRunId != task.run_id) {
            if (this.taskIdsWaitingForRun.has(previousRunId)) {
                this.taskIdsWaitingForRun.get(previousRunId).delete(task.id);
            }
            var previousRunOfTask = this.runsStore.get(previousRunId);
            if (previousRunOfTask) {
                var updatedTaskIds = new Set(previousRunOfTask.task_ids);
                updatedTaskIds.delete(task.id);
                this.updateRunInStore(previousRunOfTask, updatedTaskIds);
            }
        }
    };
    RunRealtimeSubscriptions.prototype.updateRunInStore = function (newRun, taskIds) {
        var mappedItem = this.storableDataService.updateInStores(newRun, undefined, undefined, {
            taskIds: Array.from(taskIds)
        });
        this.storableRealtimeSubscriptions.runEventCallbacks(runs_consts_1.RunEvents.UPDATED, mappedItem);
    };
    RunRealtimeSubscriptions.prototype.taskRemovedFromRun = function (task, existingRun) {
        var _a;
        return !task.run_id && ((_a = existingRun === null || existingRun === void 0 ? void 0 : existingRun.task_ids) === null || _a === void 0 ? void 0 : _a.includes(task.id));
    };
    RunRealtimeSubscriptions.prototype.taskAddedToRun = function (task, existingRun) {
        var _a;
        return task.run_id && !((_a = existingRun.task_ids) === null || _a === void 0 ? void 0 : _a.includes(task.id));
    };
    RunRealtimeSubscriptions.prototype.backupTasksUntilRunIsCreated = function (task) {
        if (!task.run_id) {
            return;
        }
        if (!this.taskIdsWaitingForRun.has(task.run_id)) {
            this.taskIdsWaitingForRun.set(task.run_id, new Set());
        }
        this.taskIdsWaitingForRun.get(task.run_id).add(task.id);
    };
    return RunRealtimeSubscriptions;
}());
exports.default = RunRealtimeSubscriptions;
//# sourceMappingURL=run-realtime-subscriptions.js.map