"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "OctoprintClient", {
    enumerable: true,
    get: function() {
        return OctoprintClient;
    }
});
const _fs = /*#__PURE__*/ _interop_require_wildcard(require("fs"));
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _formdata = /*#__PURE__*/ _interop_require_default(require("form-data"));
const _octoprintserviceconstants = require("./constants/octoprint-service.constants");
const _eventconstants = require("../../constants/event.constants");
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
const _octoprintapiroutes = require("./octoprint-api.routes");
const _axios = /*#__PURE__*/ _interop_require_default(require("axios"));
const _fileutils = require("./utils/file.utils");
const _node = require("@sentry/node");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
class OctoprintClient extends _octoprintapiroutes.OctoprintRoutes {
    eventEmitter2;
    httpClient;
    logger;
    constructor({ settingsStore, httpClient, loggerFactory, eventEmitter2 }){
        super({
            settingsStore
        });
        this.httpClient = httpClient;
        this.eventEmitter2 = eventEmitter2;
        this.logger = loggerFactory(OctoprintClient.name);
    }
    async getApiVersion(login, timeout) {
        const { url, options } = this.prepareRequest(login, this.apiVersion, timeout);
        return await this.httpClient.get(url, options);
    }
    async getServer(login) {
        const { url, options } = this.prepareRequest(login, this.apiServer);
        return await this.httpClient.get(url, options);
    }
    async login(login) {
        const { url, options } = this.prepareRequest(login, this.apiLogin);
        return await this.httpClient.post(url, {}, options);
    }
    async sendConnectionCommand(login, commandData) {
        const { url, options, data } = this.prepareJsonRequest(login, this.apiConnection, commandData);
        await this.httpClient.post(url, data, options);
    }
    async sendPrintHeadJogCommand(login, amounts) {
        const axesToHome = {
            x: amounts.x ?? 0,
            y: amounts.y ?? 0,
            z: amounts.z ?? 0
        };
        const commandData = {
            command: "jog",
            ...axesToHome
        };
        return this.sendPrintHeadCommand(login, commandData);
    }
    async sendPrintHeadHomeCommand(login, axes) {
        const axesToHome = [
            ...axes.x ? [
                "x"
            ] : [],
            ...axes.y ? [
                "y"
            ] : [],
            ...axes.z ? [
                "z"
            ] : []
        ];
        const commandData = {
            command: "home",
            axes: axesToHome
        };
        return this.sendPrintHeadCommand(login, commandData);
    }
    async sendPrintHeadCommand(login, commandData) {
        const { url, options, data } = this.prepareJsonRequest(login, this.apiPrinterHead, commandData);
        const response = await this.httpClient.post(url, data, options);
        return response?.data;
    }
    async sendCustomGCodeCommand(login, commandString) {
        const { url, options, data } = this.prepareJsonRequest(login, this.apiPrinterCustomCommand, {
            command: commandString
        });
        const response = await this.httpClient.post(url, data, options);
        return response?.data;
    }
    async getJob(login) {
        const { url, options } = this.prepareRequest(login, this.apiJob);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async sendJobCommand(login, commandData) {
        const { url, options, data } = this.prepareJsonRequest(login, this.apiJob, commandData);
        const response = await this.httpClient.post(url, data, options);
        return response?.data;
    }
    async sendBedTempCommand(login, targetTemp) {
        const { url, options, data } = this.prepareJsonRequest(login, this.apiPrinterBed, this.getBedTargetCommand(targetTemp));
        const response = await this.httpClient.post(url, data, options);
        return response?.data;
    }
    async getSettings(login) {
        const { url, options } = this.prepareRequest(login, this.apiSettingsPart);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async updatePrinterNameSetting(login, printerName) {
        const { url, options } = this.prepareRequest(login, this.apiSettingsPart);
        const settingPatch = this.printerNameSetting(printerName);
        const response = await this.httpClient.post(url, settingPatch, options);
        return response?.data;
    }
    async updateFirmwareUpdaterSettings(login, firmwareUpdateConfig) {
        const { url, options } = this.prepareRequest(login, this.apiSettingsPart);
        const settingPatch = this.pluginFirmwareUpdaterSettings(firmwareUpdateConfig);
        const response = await this.httpClient.post(url, settingPatch, options);
        return response?.data;
    }
    async setGCodeAnalysis(login, enabled) {
        const { url, options } = this.prepareRequest(login, this.apiSettingsPart);
        const settingPatch = this.gcodeAnalysisSetting(enabled);
        const response = await this.httpClient.post(url, settingPatch, options);
        return response?.data;
    }
    async getCurrentUser(login) {
        const { url, options } = this.prepareRequest(login, this.apiCurrentUser);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getAdminUserOrDefault(login) {
        const currentUser = await this.getCurrentUser(login);
        return currentUser?.name;
    }
    async getUsers(login) {
        const { url, options } = this.prepareRequest(login, this.apiUsers);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getLocalFiles(login, recursive = false) {
        const { url, options } = this.prepareRequest(login, this.apiGetFiles(recursive));
        const response = await this.httpClient.get(url, options);
        return response?.data?.files?.filter((f)=>f.date).map((f)=>{
            return (0, _fileutils.normalizePrinterFile)(f);
        }) || [];
    }
    async getFile(login, path) {
        const pathUrl = this.apiFile(path);
        const { url, options } = this.prepareRequest(login, pathUrl);
        const response = await this.httpClient.get(url, options);
        try {
            return (0, _fileutils.normalizePrinterFile)(response?.data);
        } catch (e) {
            (0, _node.captureException)(e);
            this.logger.error("File was empty or normalization failed");
            return;
        }
    }
    async downloadFile(login, path) {
        const pathUrl = this.downloadFileLocal(path);
        const { url, options } = this.prepareRequest(login, pathUrl);
        return await this.httpClient.get(url, {
            responseType: "stream",
            ...options
        });
    }
    async createFolder(login, path, foldername) {
        const { url, options } = this.prepareRequest(login, this.apiFilesLocal);
        const formData = new _formdata.default();
        formData.append("path", path);
        formData.append("foldername", foldername);
        const headers = {
            ...options.headers,
            ...formData.getHeaders(),
            "Content-Length": formData.getLengthSync()
        };
        const response = await this.httpClient.post(url, formData, {
            headers
        });
        return response?.data;
    }
    async moveFileOrFolder(login, path, destination) {
        const { url, options } = this.prepareRequest(login, this.apiFile(path));
        const command = this.moveFileCommand(destination);
        const response = await this.httpClient.post(url, command, options);
        return response?.data;
    }
    async postSelectPrintFile(login, path, print) {
        const { url, options } = this.prepareRequest(login, this.apiFile(path));
        const command = this.selectCommand(print);
        await this.httpClient.post(url, command, options);
    }
    async uploadFileAsMultiPart(login, multerFileOrBuffer, commands, token) {
        const { url, options } = this.prepareRequest(login, this.apiFilesLocal, null, _octoprintserviceconstants.multiPartContentType);
        const formData = new _formdata.default();
        if (commands.select) {
            formData.append("select", "true");
        }
        if (commands.print) {
            formData.append("print", "true");
        }
        let source = multerFileOrBuffer.buffer;
        const isPhysicalFile = !source;
        if (isPhysicalFile) {
            source = (0, _fs.createReadStream)(multerFileOrBuffer.path);
        }
        formData.append("file", source, {
            filename: multerFileOrBuffer.originalname
        });
        const result = await new Promise((resolve, reject)=>{
            return formData.getLength((err, length)=>{
                if (err) resolve(null);
                resolve(length);
            });
        });
        try {
            const headers = {
                ...options.headers,
                ...formData.getHeaders(),
                "Content-Length": result
            };
            const response = await (0, _axios.default)({
                method: "POST",
                url,
                data: formData,
                headers,
                onUploadProgress: (p)=>{
                    if (token) {
                        this.eventEmitter2.emit(`${(0, _eventconstants.uploadProgressEvent)(token)}`, token, p);
                    }
                }
            });
            return response.data;
        } catch (e) {
            this.eventEmitter2.emit(`${(0, _eventconstants.uploadProgressEvent)(token)}`, token, {
                failed: true
            }, e);
            let data;
            try {
                data = JSON.parse(e.response?.body);
            } catch  {
                data = e.response?.body;
            }
            throw new _runtimeexceptions.ExternalServiceError({
                error: e.message,
                statusCode: e.response?.statusCode,
                data,
                success: false,
                stack: e.stack
            }, "OctoPrint");
        }
    }
    async deleteFileOrFolder(login, path) {
        const { url, options } = this.prepareRequest(login, this.apiFile(path));
        const response = await this.httpClient.delete(url, options);
        return response?.data;
    }
    async getPrinterCurrent(login, history, limit, exclude) {
        const pathUrl = this.apiPrinterCurrent(history, limit, exclude);
        const { url, options } = this.prepareRequest(login, pathUrl);
        return await this.httpClient.get(url, options);
    }
    async getConnection(login) {
        const { url, options } = this.prepareRequest(login, this.apiConnection);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getPrinterProfiles(login) {
        const { url, options } = this.prepareRequest(login, this.apiPrinterProfiles);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async postSoftwareUpdate(login, targets) {
        const { url, options } = this.prepareJsonRequest(login, this.pluginSoftwareUpdateUpdate, {
            targets
        });
        const response = await this.httpClient.post(url, {}, options);
        return response?.data;
    }
    async getPluginManagerPlugins(login) {
        const { url, options } = this.prepareRequest(login, this.pluginManagerPlugins);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getPluginManagerPlugin(login, pluginName) {
        const { url, options } = this.prepareRequest(login, this.pluginManagerPlugin(pluginName));
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async postApiPluginManagerCommand(login, pluginCommand, pluginUrl) {
        const { url, options } = this.prepareRequest(login, this.apiPluginManager);
        const command = this.pluginManagerCommand(pluginCommand, pluginUrl);
        const response = await this.httpClient.post(url, command, options);
        return response?.data;
    }
    async postPluginFirmwareUpdateFlash(currentPrinterId, login, firmwarePath) {
        const { url, options } = this.prepareRequest(login, this.pluginFirmwareUpdaterFlash, null, _octoprintserviceconstants.multiPartContentType);
        const formData = new _formdata.default();
        formData.append("port", "/dev/op2");
        formData.append("profile", "default");
        const filename = _path.default.basename(firmwarePath);
        const fileReadStream = _fs.default.createReadStream(firmwarePath);
        formData.append("file", fileReadStream, {
            filename
        });
        try {
            const headers = {
                ...options.headers,
                ...formData.getHeaders()
            };
            const response = await this.httpClient.post(url, {
                body: formData,
                headers,
                uploadProgress: (p)=>{
                    if (currentPrinterId) {
                        this.eventEmitter2.emit(`${(0, _eventconstants.firmwareFlashUploadEvent)(currentPrinterId)}`, currentPrinterId, p);
                    }
                }
            });
            return response?.data;
        } catch (e) {
            this.eventEmitter2.emit(`${(0, _eventconstants.uploadProgressEvent)(currentPrinterId)}`, currentPrinterId, {
                failed: true
            }, e);
            let data;
            try {
                data = JSON.parse(e.response?.body);
            } catch  {
                data = e.response?.body;
            }
            throw new _runtimeexceptions.ExternalServiceError({
                error: e.message,
                statusCode: e.response?.statusCode,
                data,
                success: false,
                stack: e.stack
            }, "OctoPrint");
        }
    }
    async getPluginFirmwareUpdateStatus(login) {
        const { url, options } = this.prepareRequest(login, this.pluginFirmwareUpdaterStatus);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async fetchOctoPrintPlugins() {
        const { url, options } = this.prepareAnonymousRequest(_octoprintserviceconstants.pluginRepositoryUrl);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getSystemInfo(login) {
        const { url, options } = this.prepareRequest(login, this.apiSystemInfo);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getSystemCommands(login) {
        const { url, options } = this.prepareRequest(login, this.apiSystemCommands);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async postServerRestartCommand(login) {
        const { url, options } = this.prepareRequest(login, this.apiServerRestartCommand);
        const response = await this.httpClient.post(url, {}, options);
        return response?.data;
    }
    async getSoftwareUpdateCheck(login, force) {
        const { url, options } = this.prepareRequest(login, this.apiSoftwareUpdateCheck(force));
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getPluginPiSupport(login) {
        const { url, options } = this.prepareRequest(login, this.apiPluginPiSupport);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async deleteTimeLapse(login, fileName) {
        const path = `${this.apiTimelapse}/${fileName}`;
        const { url, options } = this.prepareRequest(login, path);
        const response = await this.httpClient.delete(url, options);
        return response?.data;
    }
    async listUnrenderedTimeLapses(login) {
        const path = `${this.apiTimelapse}?unrendered=true`;
        const { url, options } = this.prepareRequest(login, path);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async listProfiles(login) {
        const { url, options } = this.prepareRequest(login, this.apiProfiles);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getBackupOverview(login) {
        const { url, options } = this.prepareRequest(login, this.pluginBackupIndex);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async getBackups(login) {
        const { url, options } = this.prepareRequest(login, this.pluginBackupEndpoint);
        const response = await this.httpClient.get(url, options);
        return response?.data;
    }
    async createBackup(login, excludeArray) {
        const { url, options } = this.prepareRequest(login, this.pluginBackupEndpoint);
        const response = await this.httpClient.post(url, {
            exclude: excludeArray
        }, options);
        return response?.data;
    }
    async getDownloadBackupStream(login, filename) {
        const { url, options } = this.prepareRequest(login, this.pluginBackupFileDownload(filename));
        const response = await this.httpClient.get(url, {
            responseType: "stream",
            ...options
        }).catch((e)=>{
            throw new _runtimeexceptions.ExternalServiceError({
                error: e.message,
                statusCode: e.response?.statusCode,
                success: false,
                stack: e.stack
            }, "OctoPrint");
        });
        return response.data;
    }
    async forwardRestoreBackupFileStream(login, buffer) {
        const { url, options } = this.prepareRequest(login, this.pluginBackupFileRestore, null, _octoprintserviceconstants.multiPartContentType);
        const formData = new _formdata.default();
        formData.append("file", buffer, {
            filename: "op-fdmm-restore.zip"
        });
        const response = await this.httpClient.post(url, formData, {
            headers: {
                ...options.headers,
                ...formData.getHeaders()
            }
        }).catch((e)=>{
            throw new _runtimeexceptions.ExternalServiceError({
                error: e.message,
                statusCode: e.response?.statusCode,
                success: false,
                stack: e.stack
            }, "OctoPrint");
        });
        return response?.data;
    }
    async deleteBackup(login, filename) {
        const { url, options } = this.prepareRequest(login, this.pluginBackupFile(filename));
        const response = await this.httpClient.delete(url, options);
        return response?.data;
    }
}

//# sourceMappingURL=octoprint.client.js.map