"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "OctoprintClient", {
    enumerable: true,
    get: function() {
        return OctoprintClient;
    }
});
const _formdata = /*#__PURE__*/ _interop_require_default(require("form-data"));
const _eventconstants = require("../../constants/event.constants");
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
const _octoprintapiroutes = require("./octoprint-api.routes");
const _fileutils = require("./utils/file.utils");
const _octoprinthttpclientbuilder = require("./utils/octoprint-http-client.builder");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
class OctoprintClient extends _octoprintapiroutes.OctoprintRoutes {
    httpClientFactory;
    eventEmitter2;
    settingsStore;
    logger;
    constructor(loggerFactory, httpClientFactory, eventEmitter2, settingsStore){
        super(), this.httpClientFactory = httpClientFactory, this.eventEmitter2 = eventEmitter2, this.settingsStore = settingsStore;
        this.logger = loggerFactory(OctoprintClient.name);
    }
    async getApiVersion(login) {
        return await this.createClient(login).get(this.apiVersion);
    }
    async getServer(login) {
        return await this.createClient(login).get(this.apiServer);
    }
    async login(login) {
        return await this.createClient(login).post(this.apiLogin, {
            passive: true
        });
    }
    async sendConnectionCommand(login, commandData) {
        await this.createClient(login).post(this.apiConnection, commandData);
    }
    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) {
        await this.createClient(login).post(this.apiPrinterHead, commandData);
    }
    async sendCustomGCodeCommand(login, commandString) {
        await this.createClient(login).post(this.apiPrinterCustomCommand, {
            command: commandString
        });
    }
    async getJob(login) {
        return await this.createClient(login).get(this.apiJob);
    }
    async sendJobCommand(login, commandData) {
        return await this.createClient(login).post(this.apiJob, commandData);
    }
    async sendBedTempCommand(login, targetTemp) {
        const data = this.getBedTargetCommand(targetTemp);
        return await this.createClient(login).post(this.apiPrinterBed, data);
    }
    async getSettings(login) {
        return await this.createClient(login).get(this.apiSettingsPart);
    }
    async updatePrinterNameSetting(login, printerName) {
        const settingPatch = this.printerNameSetting(printerName);
        return await this.createClient(login).post(this.apiSettingsPart, settingPatch);
    }
    async getCurrentUser(login) {
        return await this.createClient(login).get(this.apiCurrentUser);
    }
    async getAdminUserOrDefault(login) {
        const currentUserResponse = await this.getCurrentUser(login);
        return currentUserResponse?.data?.name;
    }
    async getUsers(login) {
        return await this.createClient(login).get(this.apiUsers);
    }
    async getLocalFiles(login, recursive = false) {
        const response = await this.createClient(login).get(this.apiGetFiles(recursive));
        return response?.data?.files?.filter((f)=>f.date && f.type === "machinecode").map((f)=>{
            return (0, _fileutils.normalizePrinterFile)(f);
        }) || [];
    }
    async getFile(login, path) {
        const urlPath = this.apiFile(path);
        const response = await this.createClient(login).get(urlPath);
        return (0, _fileutils.normalizePrinterFile)(response?.data);
    }
    async downloadFile(login, path) {
        const urlPath = this.downloadFileLocal(path);
        return await this.createClient(login).get(urlPath, {
            responseType: "stream"
        });
    }
    async getFileChunk(login, filePath, startBytes, endBytes) {
        const pathUrl = this.downloadFileLocal(filePath);
        return await this.createClient(login, (o)=>o.withHeaders({
                Range: `bytes=${startBytes}-${endBytes}`
            })).get(pathUrl);
    }
    async createFolder(login, path, foldername) {
        const formData = new _formdata.default();
        formData.append("path", path);
        formData.append("foldername", foldername);
        const headers = {
            ...formData.getHeaders(),
            "Content-Length": formData.getLengthSync().toString()
        };
        return await this.createClient(login, (o)=>o.withHeaders(headers)).post(this.apiFilesLocal, formData);
    }
    async moveFileOrFolder(login, path, destination) {
        const command = this.moveFileCommand(destination);
        return await this.createClient(login).post(this.apiFile(path), command);
    }
    async postSelectPrintFile(login, path, print) {
        const command = this.selectCommand(print);
        await this.createClient(login).post(this.apiFile(path), command);
    }
    async uploadFileAsMultiPart(login, stream, fileName, contentLength, startPrint, progressToken) {
        const urlPath = this.apiFilesLocal;
        const formData = new _formdata.default();
        if (startPrint) {
            formData.append("print", "true");
        }
        formData.append("file", stream, {
            filename: fileName,
            knownLength: contentLength
        });
        const result = await new Promise((resolve, reject)=>{
            return formData.getLength((err, length)=>{
                if (err) reject(new Error("Could not retrieve formData length"));
                resolve(length);
            });
        });
        try {
            const response = await this.createClient(login, (builder)=>builder.withMultiPartFormData().withTimeout(this.settingsStore.getTimeoutSettings().apiUploadTimeout).withHeaders({
                    ...formData.getHeaders(),
                    "Content-Length": result.toString()
                }).withOnUploadProgress((p)=>{
                    if (progressToken) {
                        this.eventEmitter2.emit(`${(0, _eventconstants.uploadProgressEvent)(progressToken)}`, progressToken, p);
                    }
                })).post(urlPath, formData);
            if (progressToken) {
                this.eventEmitter2.emit(`${(0, _eventconstants.uploadDoneEvent)(progressToken)}`, progressToken);
            }
            return response.data;
        } catch (e) {
            if (progressToken) {
                this.eventEmitter2.emit(`${(0, _eventconstants.uploadFailedEvent)(progressToken)}`, progressToken, e?.message);
            }
            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) {
        await this.createClient(login).delete(this.apiFile(path));
    }
    async getPrinterCurrent(login, history, limit, exclude) {
        const pathUrl = this.apiPrinterCurrent(history, limit, exclude);
        return await this.createClient(login).get(pathUrl);
    }
    async getConnection(login) {
        return await this.createClient(login).get(this.apiConnection);
    }
    async getPrinterProfiles(login) {
        return await this.createClient(login).get(this.apiPrinterProfiles);
    }
    async getSystemInfo(login) {
        return await this.createClient(login).get(this.apiSystemInfo);
    }
    async getSystemCommands(login) {
        return await this.createClient(login).get(this.apiSystemCommands);
    }
    async postServerRestartCommand(login) {
        await this.createClient(login).post(this.apiServerRestartCommand);
    }
    createClient(login, buildFluentOptions) {
        const baseAddress = login.printerURL;
        return this.createAnonymousClient(baseAddress, (o)=>{
            if (buildFluentOptions) {
                buildFluentOptions(o);
            }
            o.withXApiKeyHeader(login.apiKey);
        });
    }
    createAnonymousClient(baseAddress, buildFluentOptions) {
        const builder = new _octoprinthttpclientbuilder.OctoprintHttpClientBuilder();
        return this.httpClientFactory.createClientWithBaseUrl(builder, baseAddress, (b)=>{
            if (buildFluentOptions) {
                buildFluentOptions(b);
            }
        });
    }
}

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