"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.exportWorkspace = exports.exportArtifact = exports.importArtifact = exports.importWorkspace = void 0;
const tslib_1 = require("tslib");
const logger_1 = require("@refloat/logger");
const promises_1 = require("stream/promises");
const path_1 = require("path");
const fs_1 = require("fs");
const promises_2 = require("fs/promises");
const node_fetch_1 = (0, tslib_1.__importDefault)(require("node-fetch"));
const glob_1 = (0, tslib_1.__importDefault)(require("glob"));
const tar_1 = (0, tslib_1.__importDefault)(require("tar"));
const api_client_1 = require("../api/api-client");
const config_1 = require("../config");
async function importWorkspace({ name, buildId, cwd = process.cwd(), }) {
    const res = await (0, node_fetch_1.default)(url(`workspace/import/${buildId}`, name), {
        compress: false,
        headers: await getHeaders(),
    });
    if (res.status === 200) {
        await (0, promises_1.pipeline)(res.body, tar_1.default.extract({
            cwd,
            onwarn: (message) => loggers.importWorkspace.warn(message),
            onentry: (entry) => loggers.importWorkspace.info('extracting', { file: entry.path }),
        }));
    }
    else {
        throw new Error(`HTTP Error ${res.status}: ${res.statusText}`);
    }
}
exports.importWorkspace = importWorkspace;
async function importArtifact(name, { buildId, path = name, cwd = process.cwd(), }) {
    const headers = await getHeaders();
    const res = await (0, node_fetch_1.default)(url(`artifact/import/${buildId}`, name), {
        headers,
        compress: true,
    });
    if (res.status === 200) {
        const dest = (0, path_1.resolve)(cwd, path);
        await (0, promises_2.mkdir)((0, path_1.dirname)(dest), { recursive: true });
        await (0, promises_1.pipeline)(res.body, (0, fs_1.createWriteStream)(dest));
    }
    else {
        throw new Error(`HTTP Error ${res.status}: ${res.statusText}`);
    }
}
exports.importArtifact = importArtifact;
async function exportArtifact(patterns, { stepId, name, cwd = process.cwd(), }) {
    const [headers, files] = await Promise.all([
        getHeaders(),
        Promise.all(patterns.map((pattern) => matchGlob(pattern, cwd, loggers.exportArtifact))).then((files) => files.flat()),
    ]);
    if (name && files.length > 1) {
        throw new Error(`Artifact name provided but pattern matched more than one file`);
    }
    await Promise.all(files.map(async (file) => {
        loggers.exportArtifact.info('sending', name ? { file, name } : { file });
        const res = await (0, node_fetch_1.default)(url(`artifact/export/${stepId}`, name !== null && name !== void 0 ? name : file), {
            headers,
            method: 'PUT',
            compress: true,
            body: (0, fs_1.createReadStream)(file),
        });
        if (res.status !== 200) {
            throw new Error(`HTTP Error ${res.status}: ${res.statusText}`);
        }
    }));
}
exports.exportArtifact = exportArtifact;
async function exportWorkspace(patterns, { buildId, name, cwd = process.cwd() }) {
    const [headers, files] = await Promise.all([
        getHeaders(),
        Promise.all(patterns.map((pattern) => matchGlob(pattern, cwd, loggers.exportWorkspace))),
    ]);
    await (0, node_fetch_1.default)(url('workspace/export/' + buildId, name), {
        headers,
        method: 'PUT',
        compress: false,
        body: tar_1.default.create({
            cwd,
            gzip: true,
            onwarn: (message) => loggers.importWorkspace.warn(message),
            filter: (file) => {
                loggers.exportWorkspace.info('archiving', { file });
                return true;
            },
        }, files.flat()),
    });
}
exports.exportWorkspace = exportWorkspace;
async function getToken() {
    const config = config_1.Configuration.get();
    const api = new api_client_1.APIClient(config.api);
    const { token } = await api.register(config);
    return token;
}
async function matchGlob(pattern, cwd, logger) {
    return new Promise((resolve, reject) => (0, glob_1.default)(pattern, { cwd }, (error, matches) => {
        if (error) {
            reject(error);
        }
        else if (matches.length) {
            logger.debug('pattern matches', { pattern, matches });
            resolve(matches);
        }
        else {
            throw new Error(`no matches found for "${pattern}"`);
        }
    }));
}
async function getHeaders() {
    return {
        Authorization: `Bearer ${await getToken()}`,
    };
}
function url(endpoint, name) {
    const config = config_1.Configuration.get();
    const url = new URL(config.api.href + 'api/agent/' + endpoint);
    url.searchParams.append('name', name);
    return url.href;
}
const loggers = {
    importWorkspace: logger_1.Logger.create('import-workspace'),
    exportWorkspace: logger_1.Logger.create('export-workspace'),
    exportArtifact: logger_1.Logger.create('export-artifact'),
};
//# sourceMappingURL=workspace.js.map