"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainThreadTasks = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const ide_connection_1 = require("@opensumi/ide-connection");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const common_1 = require("@opensumi/ide-task/lib/common");
const task_1 = require("@opensumi/ide-task/lib/common/task");
const ide_workspace_1 = require("@opensumi/ide-workspace");
const vscode_1 = require("../../../common/vscode");
const tasks_1 = require("../../../common/vscode/tasks");
var TaskHandleDTO;
(function (TaskHandleDTO) {
    function is(value) {
        const candidate = value;
        return candidate && (0, ide_core_common_1.isString)(candidate.id) && !!candidate.workspaceFolder;
    }
    TaskHandleDTO.is = is;
})(TaskHandleDTO || (TaskHandleDTO = {}));
var TaskExecutionDTO;
(function (TaskExecutionDTO) {
    function from(value) {
        return {
            id: value.id,
            task: TaskDTO.from(value.task),
        };
    }
    TaskExecutionDTO.from = from;
})(TaskExecutionDTO || (TaskExecutionDTO = {}));
var TaskProcessStartedDTO;
(function (TaskProcessStartedDTO) {
    function from(value, processId) {
        return {
            id: value.id,
            processId,
        };
    }
    TaskProcessStartedDTO.from = from;
})(TaskProcessStartedDTO || (TaskProcessStartedDTO = {}));
var TaskProcessEndedDTO;
(function (TaskProcessEndedDTO) {
    function from(value, exitCode) {
        return {
            id: value.id,
            exitCode,
        };
    }
    TaskProcessEndedDTO.from = from;
})(TaskProcessEndedDTO || (TaskProcessEndedDTO = {}));
var TaskDefinitionDTO;
(function (TaskDefinitionDTO) {
    function from(value) {
        const result = Object.assign(Object.create(null), value);
        delete result._key;
        return result;
    }
    TaskDefinitionDTO.from = from;
    function to(value, executeOnly, context) {
        let result = context.createTaskIdentifier(value, console);
        if (result === undefined && executeOnly) {
            result = {
                _key: (0, ide_core_common_1.uuid)(),
                type: '$executeOnly',
            };
        }
        return result;
    }
    TaskDefinitionDTO.to = to;
})(TaskDefinitionDTO || (TaskDefinitionDTO = {}));
var TaskPresentationOptionsDTO;
(function (TaskPresentationOptionsDTO) {
    function from(value) {
        if (value === undefined || value === null) {
            return undefined;
        }
        return Object.assign(Object.create(null), value);
    }
    TaskPresentationOptionsDTO.from = from;
    function to(value) {
        if (value === undefined || value === null) {
            return task_1.PresentationOptions.defaults;
        }
        return Object.assign(Object.create(null), task_1.PresentationOptions.defaults, value);
    }
    TaskPresentationOptionsDTO.to = to;
})(TaskPresentationOptionsDTO || (TaskPresentationOptionsDTO = {}));
var RunOptionsDTO;
(function (RunOptionsDTO) {
    function from(value) {
        if (value === undefined || value === null) {
            return undefined;
        }
        return Object.assign(Object.create(null), value);
    }
    RunOptionsDTO.from = from;
    function to(value) {
        if (value === undefined || value === null) {
            return task_1.RunOptions.defaults;
        }
        return Object.assign(Object.create(null), task_1.RunOptions.defaults, value);
    }
    RunOptionsDTO.to = to;
})(RunOptionsDTO || (RunOptionsDTO = {}));
var ProcessExecutionOptionsDTO;
(function (ProcessExecutionOptionsDTO) {
    function from(value) {
        if (value === undefined || value === null) {
            return undefined;
        }
        return {
            cwd: value.cwd,
            env: value.env,
        };
    }
    ProcessExecutionOptionsDTO.from = from;
    function to(value) {
        if (value === undefined || value === null) {
            return task_1.CommandOptions.defaults;
        }
        return {
            cwd: value.cwd || task_1.CommandOptions.defaults.cwd,
            env: value.env,
        };
    }
    ProcessExecutionOptionsDTO.to = to;
})(ProcessExecutionOptionsDTO || (ProcessExecutionOptionsDTO = {}));
var ProcessExecutionDTO;
(function (ProcessExecutionDTO) {
    function is(value) {
        const candidate = value;
        return candidate && !!candidate.process;
    }
    ProcessExecutionDTO.is = is;
    function from(value) {
        const process = (0, ide_core_common_1.isString)(value.name) ? value.name : value.name.value;
        const args = value.args ? value.args.map((value) => ((0, ide_core_common_1.isString)(value) ? value : value.value)) : [];
        const result = {
            process,
            args,
        };
        if (value.options) {
            result.options = ProcessExecutionOptionsDTO.from(value.options);
        }
        return result;
    }
    ProcessExecutionDTO.from = from;
    function to(value) {
        const result = {
            runtime: task_1.RuntimeType.Process,
            name: value.process,
            args: value.args,
            presentation: undefined,
        };
        result.options = ProcessExecutionOptionsDTO.to(value.options);
        return result;
    }
    ProcessExecutionDTO.to = to;
})(ProcessExecutionDTO || (ProcessExecutionDTO = {}));
var ShellExecutionOptionsDTO;
(function (ShellExecutionOptionsDTO) {
    function from(value) {
        if (value === undefined || value === null) {
            return undefined;
        }
        const result = {
            cwd: value.cwd || task_1.CommandOptions.defaults.cwd,
            env: value.env,
        };
        if (value.shell) {
            result.executable = value.shell.executable;
            result.shellArgs = value.shell.args;
            result.shellQuoting = value.shell.quoting;
        }
        return result;
    }
    ShellExecutionOptionsDTO.from = from;
    function to(value) {
        if (value === undefined || value === null) {
            return undefined;
        }
        const result = {
            cwd: value.cwd,
            env: value.env,
        };
        if (value.executable) {
            result.shell = {
                executable: value.executable,
            };
            if (value.shellArgs) {
                result.shell.args = value.shellArgs;
            }
            if (value.shellQuoting) {
                result.shell.quoting = value.shellQuoting;
            }
        }
        return result;
    }
    ShellExecutionOptionsDTO.to = to;
})(ShellExecutionOptionsDTO || (ShellExecutionOptionsDTO = {}));
var ShellExecutionDTO;
(function (ShellExecutionDTO) {
    function is(value) {
        const candidate = value;
        return candidate && (!!candidate.commandLine || !!candidate.command);
    }
    ShellExecutionDTO.is = is;
    function from(value) {
        const result = {};
        if (value.name &&
            (0, ide_core_common_1.isString)(value.name) &&
            (value.args === undefined || value.args === null || value.args.length === 0)) {
            result.commandLine = value.name;
        }
        else {
            result.command = value.name;
            result.args = value.args;
        }
        if (value.options) {
            result.options = ShellExecutionOptionsDTO.from(value.options);
        }
        return result;
    }
    ShellExecutionDTO.from = from;
    function to(value) {
        const result = {
            runtime: task_1.RuntimeType.Shell,
            name: value.commandLine ? value.commandLine : value.command,
            args: value.args,
            presentation: undefined,
        };
        if (value.options) {
            result.options = ShellExecutionOptionsDTO.to(value.options);
        }
        return result;
    }
    ShellExecutionDTO.to = to;
})(ShellExecutionDTO || (ShellExecutionDTO = {}));
var CustomExecutionDTO;
(function (CustomExecutionDTO) {
    function is(value) {
        const candidate = value;
        return candidate && candidate.customExecution === 'customExecution';
    }
    CustomExecutionDTO.is = is;
    function from() {
        return {
            customExecution: 'customExecution',
        };
    }
    CustomExecutionDTO.from = from;
    function to() {
        return {
            runtime: task_1.RuntimeType.CustomExecution,
            presentation: undefined,
        };
    }
    CustomExecutionDTO.to = to;
})(CustomExecutionDTO || (CustomExecutionDTO = {}));
var CustomExecution2DTO;
(function (CustomExecution2DTO) {
    function is(value) {
        const candidate = value;
        return candidate && candidate.customExecution === 'customExecution2';
    }
    CustomExecution2DTO.is = is;
    function from() {
        return {
            customExecution: 'customExecution2',
        };
    }
    CustomExecution2DTO.from = from;
    function to() {
        return {
            runtime: task_1.RuntimeType.CustomExecution2,
            presentation: undefined,
        };
    }
    CustomExecution2DTO.to = to;
})(CustomExecution2DTO || (CustomExecution2DTO = {}));
var TaskSourceDTO;
(function (TaskSourceDTO) {
    function from(value) {
        const result = {
            label: value.label,
        };
        if (value.kind === task_1.TaskSourceKind.Extension) {
            result.extensionId = value.extension;
            if (value.workspaceFolder) {
                result.scope = value.workspaceFolder.uri;
            }
            else {
                result.scope = value.scope;
            }
        }
        else if (value.kind === task_1.TaskSourceKind.Workspace) {
            result.extensionId = '$core';
            result.scope = value.config.workspaceFolder.uri;
        }
        return result;
    }
    TaskSourceDTO.from = from;
    function to(value, workspace) {
        let scope;
        let workspaceFolder;
        const folders = workspace.tryGetRoots().map((stat) => ide_core_common_1.Uri.parse(stat.uri));
        if (value.scope === undefined || (typeof value.scope === 'number' && value.scope !== 1 /* TaskScope.Global */)) {
            if (workspace.tryGetRoots().map((stat) => ide_core_common_1.Uri.file(stat.uri)).length === 0) {
                scope = 1 /* TaskScope.Global */;
                workspaceFolder = undefined;
            }
            else {
                scope = 3 /* TaskScope.Folder */;
                workspaceFolder = { name: 'workspace', uri: folders[0], index: 0 };
            }
        }
        else if (typeof value.scope === 'number') {
            scope = value.scope;
        }
        else {
            scope = 3 /* TaskScope.Folder */;
            workspaceFolder = (0, ide_core_common_1.withNullAsUndefined)({
                uri: workspace.tryGetRoots().map((stat) => ide_core_common_1.Uri.parse(stat.uri))[0],
                name: workspace.getWorkspaceName(workspace.tryGetRoots().map((stat) => ide_core_common_1.URI.file(stat.uri))[0]),
                index: 0,
            });
        }
        const result = {
            kind: task_1.TaskSourceKind.Extension,
            label: value.label,
            extension: value.extensionId,
            scope,
            workspaceFolder,
        };
        return result;
    }
    TaskSourceDTO.to = to;
})(TaskSourceDTO || (TaskSourceDTO = {}));
var TaskDTO;
(function (TaskDTO) {
    function from(task) {
        if (task === undefined ||
            task === null ||
            (!task_1.CustomTask.is(task) && !task_1.ContributedTask.is(task) && !task_1.ConfiguringTask.is(task))) {
            return undefined;
        }
        const result = {
            _id: task._id,
            name: task.configurationProperties.name,
            definition: TaskDefinitionDTO.from(task.getDefinition()),
            source: TaskSourceDTO.from(task._source),
            execution: undefined,
            presentationOptions: !task_1.ConfiguringTask.is(task) && task.command
                ? TaskPresentationOptionsDTO.from(task.command.presentation)
                : undefined,
            isBackground: task.configurationProperties.isBackground,
            problemMatchers: [],
            hasDefinedMatchers: task_1.ContributedTask.is(task) ? task.hasDefinedMatchers : false,
            runOptions: RunOptionsDTO.from(task.runOptions),
        };
        if (task.configurationProperties.group) {
            result.group = task.configurationProperties.group;
        }
        if (!task_1.ConfiguringTask.is(task) && task.command) {
            if (task.command.runtime === task_1.RuntimeType.Process) {
                result.execution = ProcessExecutionDTO.from(task.command);
            }
            else if (task.command.runtime === task_1.RuntimeType.Shell) {
                result.execution = ShellExecutionDTO.from(task.command);
            }
        }
        if (task.configurationProperties.problemMatchers) {
            for (const matcher of task.configurationProperties.problemMatchers) {
                if ((0, ide_core_common_1.isString)(matcher)) {
                    result.problemMatchers.push(matcher);
                }
            }
        }
        return result;
    }
    TaskDTO.from = from;
    function to(task, workspace, executeOnly, context) {
        if (!task || typeof task.name !== 'string') {
            return undefined;
        }
        let command;
        if (task.execution) {
            if (ShellExecutionDTO.is(task.execution)) {
                command = ShellExecutionDTO.to(task.execution);
            }
            else if (ProcessExecutionDTO.is(task.execution)) {
                command = ProcessExecutionDTO.to(task.execution);
            }
            else if (CustomExecutionDTO.is(task.execution)) {
                command = CustomExecutionDTO.to();
            }
        }
        if (!command) {
            return undefined;
        }
        command.presentation = TaskPresentationOptionsDTO.to(task.presentationOptions);
        const source = TaskSourceDTO.to(task.source, workspace);
        const label = (0, ide_core_common_1.formatLocalize)('task.label', source.label, task.name);
        const definition = TaskDefinitionDTO.to(task.definition, executeOnly, context);
        const id = `${task.source.extensionId}.${definition._key}`;
        const result = new task_1.ContributedTask(id, // uuidMap.getUUID(identifier)
        source, label, definition.type, definition, command, task.hasDefinedMatchers, RunOptionsDTO.to(task.runOptions), {
            name: task.name,
            identifier: label,
            group: task.group,
            isBackground: !!task.isBackground,
            problemMatchers: task.problemMatchers.slice(),
        });
        return result;
    }
    TaskDTO.to = to;
})(TaskDTO || (TaskDTO = {}));
let MainThreadTasks = class MainThreadTasks extends ide_core_common_1.Disposable {
    constructor(rpcProtocol) {
        super();
        this.rpcProtocol = rpcProtocol;
        this.proxy = this.rpcProtocol.getProxy(vscode_1.ExtHostAPIIdentifier.ExtHostTasks);
        this.providers = new Map();
        this.context = {
            createTaskIdentifier: (identifier, reporter) => this.taskDefinitionRegistry.createTaskIdentifier(identifier, reporter),
        };
        this.addDispose(this.taskService.onDidStateChange((event) => {
            const task = event.__task;
            if (event.kind === "start" /* TaskEventKind.Start */) {
                this.logger.verbose(`task ${task._label || task._id} start`, event.terminalId);
                this.proxy.$onDidStartTask(TaskExecutionDTO.from(task.getTaskExecution()), event.terminalId);
            }
            else if (event.kind === "processStarted" /* TaskEventKind.ProcessStarted */) {
                this.logger.verbose(`task ${task._label || task._id} process start`, event.processId);
                this.proxy.$onDidStartTaskProcess(TaskProcessStartedDTO.from(task.getTaskExecution(), event.processId));
            }
            else if (event.kind === "processEnded" /* TaskEventKind.ProcessEnded */) {
                this.logger.verbose(`task ${task._label || task._id} process end`, event.exitCode);
                this.proxy.$onDidEndTaskProcess(TaskProcessEndedDTO.from(task.getTaskExecution(), event.exitCode));
            }
            else if (event.kind === "end" /* TaskEventKind.End */) {
                this.logger.verbose(`task ${task._label || task._id} end`);
                this.proxy.$onDidEndTask(TaskExecutionDTO.from(task.getTaskExecution()));
            }
        }));
    }
    dispose() {
        super.dispose();
        this.providers.forEach((item) => item.disposable.dispose());
        this.providers.clear();
    }
    $registerTaskProvider(handler, type) {
        this.logger.verbose(`register task provider ${type}, handler ${handler}`);
        const provider = {
            // @ts-ignore
            provideTasks: (validTypes) => {
                this.logger.verbose(`${type} provideTask`);
                return Promise.resolve(this.proxy.$provideTask(handler, validTypes)).then((result) => {
                    const tasks = [];
                    for (const dto of result.tasks) {
                        const task = TaskDTO.to(dto, this.workspaceService, true, this.context);
                        if (task) {
                            tasks.push(task);
                        }
                        else {
                            this.logger.error(`Task System: can not convert task: ${JSON.stringify(dto.definition, undefined, 0)}. Task will be dropped`);
                        }
                    }
                    return {
                        tasks,
                        extension: result.extension,
                        type,
                    };
                });
            },
            // @ts-ignore
            resolveTask: (task) => {
                this.logger.verbose(`${type} resolveTask`);
                return Promise.resolve(this.proxy.$resolveTask(handler, task)).then((resolvedTask) => {
                    if (resolvedTask) {
                        return TaskDTO.to(resolvedTask, this.workspaceService, true, this.context);
                    }
                    return undefined;
                });
            },
        };
        const disposable = this.taskService.registerTaskProvider(provider, type);
        this.providers.set(handler, { disposable, provider });
        return Promise.resolve();
    }
    $unregisterTaskProvider(type) {
        throw new Error('Method not implemented.');
    }
    $fetchTasks(filter) {
        return this.taskService.tasks(tasks_1.TaskFilterDTO.to(filter)).then((tasks) => {
            const result = [];
            for (const task of tasks) {
                const item = TaskDTO.from(task);
                if (item) {
                    result.push(item);
                }
            }
            return result;
        });
    }
    $executeTask(value) {
        return new Promise((resolve, reject) => {
            if (TaskHandleDTO.is(value)) {
                const workspaceFolder = this.workspaceService.getWorkspaceRootUri(ide_core_common_1.URI.from(value.workspaceFolder));
                if (workspaceFolder) {
                    this.taskService.getTask(workspaceFolder.codeUri, value.id, true).then((task) => {
                        this.taskService.run(task).then(() => {
                            // eat the error, it has already been surfaced to the user and we don't care about it here
                        });
                        const result = {
                            id: value.id,
                            task: TaskDTO.from(task),
                        };
                        resolve(result);
                    }, (_error) => {
                        reject(new Error('Task not found'));
                    });
                }
                else {
                    reject(new Error('No workspace folder'));
                }
            }
            else {
                const task = TaskDTO.to(value, this.workspaceService, true, this.context);
                this.taskService.run(task).then(() => {
                    // eat the error, it has already been surfaced to the user and we don't care about it here
                });
                const result = {
                    id: task._id,
                    task: TaskDTO.from(task),
                };
                resolve(result);
            }
        });
    }
    $createTaskId(taskDTO) {
        return new Promise((resolve, reject) => {
            const task = TaskDTO.to(taskDTO, this.workspaceService, true, this.context);
            if (task) {
                resolve(task._id);
            }
            else {
                reject(new Error('Task could not be created from DTO'));
            }
        });
    }
    async $terminateTask(executionId) {
        await this.taskService.terminateTask(executionId);
    }
};
exports.MainThreadTasks = MainThreadTasks;
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_common_1.ILogger),
    tslib_1.__metadata("design:type", Object)
], MainThreadTasks.prototype, "logger", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ITaskService),
    tslib_1.__metadata("design:type", Object)
], MainThreadTasks.prototype, "taskService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_workspace_1.IWorkspaceService),
    tslib_1.__metadata("design:type", Object)
], MainThreadTasks.prototype, "workspaceService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_common_1.ITaskDefinitionRegistry),
    tslib_1.__metadata("design:type", Object)
], MainThreadTasks.prototype, "taskDefinitionRegistry", void 0);
exports.MainThreadTasks = MainThreadTasks = tslib_1.__decorate([
    (0, di_1.Injectable)({ multiple: true }),
    tslib_1.__metadata("design:paramtypes", [Object])
], MainThreadTasks);
//# sourceMappingURL=main.thread.tasks.js.map