"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());
    });
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const ts_log_debug_1 = require("ts-log-debug");
const RestClient_1 = require("typed-rest-client/RestClient");
const constants_1 = require("../constants");
const HttpClient_1 = require("typed-rest-client/HttpClient");
const klawSync = require("klaw-sync");
const mime_types_1 = require("mime-types");
const path_1 = require("path");
const fs_extra_1 = require("fs-extra");
const file_utils_1 = require("./file-utils");
const auth_1 = __importDefault(require("./auth"));
const routes = {
    version: (params) => `${constants_1.Constants.ASSET_ROOT_URL}/${params.name}/${params.version}`,
    versions: (params) => `${constants_1.Constants.ASSET_ROOT_URL}/${params.user}/${params.collection}/versions`,
    assetfile: (params) => `${constants_1.Constants.ASSETFILE_ROOT_URL}/${params.key}`
};
class Remote {
    constructor() {
        this.auth = new auth_1.default();
    }
    getRestClient() {
        return __awaiter(this, void 0, void 0, function* () {
            const token = yield this.auth.getToken();
            const modelNestClient = new RestClient_1.RestClient('model-nest-cli', constants_1.Constants.HOST, [], {
                headers: { Authorization: `Bearer ${token}` }
            });
            return modelNestClient;
        });
    }
    getDownloadClient() {
        return __awaiter(this, void 0, void 0, function* () {
            const token = yield this.auth.getToken();
            const modelNestClient = new HttpClient_1.HttpClient('model-nest-cli', [], {
                headers: { Authorization: `Bearer ${token}` }
            });
            return modelNestClient;
        });
    }
    upload(assetName, localPath) {
        return __awaiter(this, void 0, void 0, function* () {
            const client = yield this.getRestClient();
            console.log('here');
            if (!fs.existsSync(localPath)) {
                ts_log_debug_1.$log.error(`${localPath} does not exist`);
                return;
            }
            let files = [path.relative(path.dirname(localPath), localPath)];
            if (fs.lstatSync(localPath).isDirectory()) {
                const fileStats = klawSync(localPath);
                for (const file of fileStats) {
                    if (file_utils_1.isSourceAsset(file.path)) {
                        if (path_1.dirname(file.path) != path_1.resolve(localPath)) {
                            throw Error("Root asset file (ie. fbx or obj), must be in the root of the uploaded directory");
                        }
                    }
                }
                files = fileStats.map(f => path.relative(localPath, f.path));
            }
            ts_log_debug_1.$log.debug(files);
            ts_log_debug_1.$log.debug(constants_1.Constants.HOST);
            const uploadClient = new RestClient_1.RestClient('model-nest-cli');
            try {
                const url = `asset/${encodeURIComponent(assetName)}/upload`;
                ts_log_debug_1.$log.debug(url);
                ts_log_debug_1.$log.debug(JSON.stringify({ files }, null, 2));
                const uploadUrlsResp = yield client.create(url, { files });
                ts_log_debug_1.$log.debug(uploadUrlsResp);
                const uploadUrls = uploadUrlsResp.result;
                if (uploadUrls != null) {
                    for (const filePath of Object.keys(uploadUrls)) {
                        const absPath = path.join(localPath, filePath);
                        if (fs.lstatSync(absPath).isFile()) {
                            const uploadResult = yield uploadClient.uploadStream('PUT', uploadUrls[filePath].url, fs.createReadStream(absPath), {
                                additionalHeaders: {
                                    'content-type': mime_types_1.lookup(absPath) || 'application/octet-stream'
                                }
                            });
                            ts_log_debug_1.$log.debug(uploadResult);
                        }
                    }
                }
            }
            catch (err) {
                ts_log_debug_1.$log.error(`Unexpected error:\n ${JSON.stringify(err, null, 2)}`);
                return;
            }
        });
    }
    getAssetVersion(packageVersion) {
        return __awaiter(this, void 0, void 0, function* () {
            const client = yield this.getRestClient();
            const versionEndpoint = routes.version(packageVersion);
            const resp = yield client.get(versionEndpoint);
            return resp.result;
        });
    }
    downloadAsset(workspaceDir, packageVersion, version) {
        return __awaiter(this, void 0, void 0, function* () {
            const client = yield this.getDownloadClient();
            const packageDir = path_1.join(workspaceDir, packageVersion.name);
            yield fs_extra_1.ensureDir(packageDir);
            const format = version.formats.find(f => f.derived == false);
            if (format) {
                for (const asset of format.resources) {
                    const downloadPath = routes.assetfile(asset);
                    const localPath = path_1.join(packageDir, asset.sourcePath);
                    ts_log_debug_1.$log.debug(`Downloading to ${localPath}`);
                    yield fs_extra_1.ensureDir(path_1.dirname(localPath));
                    let file = fs.createWriteStream(localPath);
                    (yield client.get(downloadPath)).message.pipe(file);
                }
            }
        });
    }
}
exports.default = Remote;
//# sourceMappingURL=remote.js.map