"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const URI_1 = require("../utils/URI");
const types_1 = require("../types");
const Queue_1 = require("../queues/Queue");
const Session_1 = __importDefault(require("../Session"));
const Copy_1 = __importDefault(require("../queues/Copy"));
const Download_1 = __importDefault(require("../queues/Download"));
const Upload_1 = __importDefault(require("../queues/Upload"));
const uniqid_1 = __importDefault(require("../utils/uniqid"));
const App_1 = __importDefault(require("../App"));
const ramda_1 = require("ramda");
function default_1(src, dest, move, filter, sid, onComplete = () => { }) {
    if (!src.length) {
        return;
    }
    const { id: fromId } = (0, URI_1.parseURI)(src[0]);
    const { id: toId, path: toPath } = (0, URI_1.parseURI)(dest);
    const from = src.map((0, ramda_1.pipe)(URI_1.parseURI, (0, ramda_1.prop)('path')));
    const id = (0, uniqid_1.default)();
    let queueType;
    let connection;
    let queue;
    const onConflict = (from, to) => {
        if (sid) {
            const action = Session_1.default.get(sid)?.action;
            if (action) {
                Queue_1.queues.get(id)?.resolve(action, true);
                return;
            }
        }
        App_1.default.onQueueUpdate(id, { type: types_1.QueueEventType.Ask, queueType, from, to, sid });
    };
    const onFinish = () => {
        Queue_1.queues.delete(id);
        App_1.default.onQueueUpdate(id, { type: types_1.QueueEventType.Complete });
        onComplete();
    };
    if (fromId == toId) {
        queueType = move ? types_1.QueueType.Move : types_1.QueueType.Copy;
        connection = fromId;
        queue = new Copy_1.default(connection, from, toPath, filter, state => App_1.default.onQueueUpdate(id, { type: types_1.QueueEventType.Update, state }), onConflict.bind(queue), error => {
            App_1.default.onError({
                type: types_1.FailureType.RemoteError,
                id: fromId,
                message: error.message ?? String(error)
            });
        }, onFinish, App_1.default.remoteWatcher, move);
    }
    else {
        queueType = (0, URI_1.isLocal)(dest) ? types_1.QueueType.Download : types_1.QueueType.Upload;
        connection = queueType == types_1.QueueType.Download ? fromId : toId;
        queue = queueType == types_1.QueueType.Download ?
            new Download_1.default(connection, from, toPath, filter, state => App_1.default.onQueueUpdate(id, { type: types_1.QueueEventType.Update, state }), onConflict.bind(queue), error => App_1.default.onError(error), onFinish) :
            new Upload_1.default(connection, from, toPath, filter, state => App_1.default.onQueueUpdate(id, { type: types_1.QueueEventType.Update, state }), onConflict.bind(queue), error => App_1.default.onError(error), onFinish, App_1.default.remoteWatcher);
    }
    Queue_1.queues.set(id, queue);
    App_1.default.onQueueUpdate(id, { type: types_1.QueueEventType.Create, queueType, connection });
    queue.create();
    return id;
}
