"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const got = require("got");
const pLimit = require("p-limit");
const uuid = require("uuid");
function default_1(initOpts) {
    const remotePrefix = initOpts.remotePrefix;
    const limitedFetch = fetch.bind(null, pLimit(initOpts.concurrency || 100));
    return new Promise((resolve, reject) => {
        resolve({
            close: () => __awaiter(this, void 0, void 0, function* () { return; }),
            fetchPackage: fetchPackage.bind(null, remotePrefix, limitedFetch),
            getCacheByEngine: (storePath, id) => __awaiter(this, void 0, void 0, function* () {
                return limitedFetch(`${remotePrefix}/getCacheByEngine`, {
                    id,
                    storePath,
                });
            }),
            importPackage: (from, to, opts) => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/importPackage`, {
                    from,
                    opts,
                    to,
                });
            }),
            prune: () => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/prune`, {});
            }),
            requestPackage: requestPackage.bind(null, remotePrefix, limitedFetch),
            saveState: () => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/saveState`, {});
            }),
            stop: () => limitedFetch(`${remotePrefix}/stop`, {}),
            updateConnections: (prefix, opts) => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/updateConnections`, {
                    opts,
                    prefix,
                });
            }),
            upload: (builtPkgLocation, opts) => __awaiter(this, void 0, void 0, function* () {
                yield limitedFetch(`${remotePrefix}/upload`, {
                    builtPkgLocation,
                    opts,
                });
            }),
        });
    });
}
exports.default = default_1;
function fetch(limit, url, body) {
    return limit(() => __awaiter(this, void 0, void 0, function* () {
        try {
            const response = yield got(url, {
                body: JSON.stringify(body),
                headers: { 'Content-Type': 'application/json' },
                method: 'POST',
                retries: () => {
                    return 100;
                },
            });
            if (!response.body) {
                return undefined;
            }
            return JSON.parse(response.body);
        }
        catch (e) {
            throw JSON.parse(e.response.body);
        }
    }));
}
function requestPackage(remotePrefix, limitedFetch, // tslint:disable-line
wantedDependency, options) {
    const msgId = uuid.v4();
    return limitedFetch(`${remotePrefix}/requestPackage`, {
        msgId,
        options,
        wantedDependency,
    })
        .then((packageResponseBody) => {
        const fetchingRawManifest = !packageResponseBody['fetchingRawManifestInProgress'] // tslint:disable-line
            ? undefined
            : limitedFetch(`${remotePrefix}/rawManifestResponse`, {
                msgId,
            });
        delete packageResponseBody['fetchingRawManifestInProgress']; // tslint:disable-line
        if (options.skipFetch) {
            return {
                body: packageResponseBody,
                fetchingRawManifest,
            };
        }
        const fetchingFiles = limitedFetch(`${remotePrefix}/packageFilesResponse`, {
            msgId,
        });
        return {
            body: packageResponseBody,
            fetchingFiles,
            fetchingRawManifest,
            finishing: Promise.all([fetchingRawManifest, fetchingFiles]).then(() => undefined),
        };
    });
}
function fetchPackage(remotePrefix, limitedFetch, // tslint:disable-line
options) {
    const msgId = uuid.v4();
    return limitedFetch(`${remotePrefix}/fetchPackage`, {
        msgId,
        options,
    })
        .then((fetchResponseBody) => {
        const fetchingRawManifest = options.fetchRawManifest
            ? limitedFetch(`${remotePrefix}/rawManifestResponse`, { msgId })
            : undefined;
        const fetchingFiles = limitedFetch(`${remotePrefix}/packageFilesResponse`, {
            msgId,
        });
        return {
            fetchingFiles,
            fetchingRawManifest,
            finishing: Promise.all([fetchingRawManifest, fetchingFiles]).then(() => undefined),
            inStoreLocation: fetchResponseBody.inStoreLocation,
        };
    });
}
//# sourceMappingURL=connectStoreController.js.map