/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import fs from 'fs';
import { mkdirIfNeeded } from '@utils/fileUtils';
import { Dispatcher } from './dispatcher';
import { StreamDispatcher } from './streamDispatcher';
export class ArtifactDispatcher extends Dispatcher {
    _type_Artifact = true;
    static from(parentScope, artifact) {
        return ArtifactDispatcher.fromNullable(parentScope, artifact);
    }
    static fromNullable(parentScope, artifact) {
        if (!artifact)
            return undefined;
        const result = parentScope.connection.existingDispatcher(artifact);
        return result || new ArtifactDispatcher(parentScope, artifact);
    }
    constructor(scope, artifact) {
        super(scope, artifact, 'Artifact', {
            absolutePath: artifact.localPath(),
        });
    }
    async pathAfterFinished(params, progress) {
        const path = await this._object.localPathAfterFinished(progress);
        return { value: path };
    }
    async saveAs(params, progress) {
        return await progress.race(new Promise((resolve, reject) => {
            this._object.saveAs(progress, async (localPath, error) => {
                if (error) {
                    reject(error);
                    return;
                }
                try {
                    await mkdirIfNeeded(params.path);
                    await fs.promises.copyFile(localPath, params.path);
                    resolve();
                }
                catch (e) {
                    reject(e);
                }
            });
        }));
    }
    async saveAsStream(params, progress) {
        return await progress.race(new Promise((resolve, reject) => {
            this._object.saveAs(progress, async (localPath, error) => {
                if (error) {
                    reject(error);
                    return;
                }
                try {
                    const readable = fs.createReadStream(localPath, { highWaterMark: 1024 * 1024 });
                    const stream = new StreamDispatcher(this, readable);
                    // Resolve with a stream, so that client starts saving the data.
                    resolve({ stream });
                    // Block the Artifact until the stream is consumed.
                    await new Promise(resolve => {
                        readable.on('close', resolve);
                        readable.on('end', resolve);
                        readable.on('error', resolve);
                    });
                }
                catch (e) {
                    reject(e);
                }
            });
        }));
    }
    async stream(params, progress) {
        const fileName = await this._object.localPathAfterFinished(progress);
        const readable = fs.createReadStream(fileName, { highWaterMark: 1024 * 1024 });
        return { stream: new StreamDispatcher(this, readable) };
    }
    async failure(params, progress) {
        const error = await this._object.failureError(progress);
        return { error: error || undefined };
    }
    async cancel(params, progress) {
        await this._object.cancel(progress);
    }
    async delete(params, progress) {
        progress.metadata.potentiallyClosesScope = true;
        await this._object.delete(progress);
        this._dispose();
    }
}
//# sourceMappingURL=artifactDispatcher.js.map