"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const base_command_1 = require("./base-command");
const locale_1 = require("@joplin/lib/locale");
const app_1 = require("./app");
const fs = require("fs-extra");
const Setting_1 = require("@joplin/lib/models/Setting");
class Command extends base_command_1.default {
    usage() {
        return 'config [name] [value]';
    }
    description() {
        return (0, locale_1._)('Gets or sets a config value. If [value] is not provided, it will show the value of [name]. If neither [name] nor [value] is provided, it will list the current configuration.');
    }
    options() {
        return [
            ['-v, --verbose', (0, locale_1._)('Also displays unset and hidden config variables.')],
            ['--export', 'Writes all settings to STDOUT as JSON including secure variables.'],
            ['--import', 'Reads in JSON formatted settings from STDIN.'],
            ['--import-file <file>', 'Reads in settings from <file>. <file> must contain valid JSON.'],
        ];
    }
    async __importSettings(inputStream) {
        return new Promise((resolve, reject) => {
            // being defensive and not attempting to settle twice
            let isSettled = false;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
            const chunks = [];
            inputStream.on('readable', () => {
                let chunk;
                while ((chunk = inputStream.read()) !== null) {
                    chunks.push(chunk);
                }
            });
            inputStream.on('end', () => {
                const json = chunks.join('');
                let settingsObj;
                try {
                    settingsObj = JSON.parse(json);
                }
                catch (error) {
                    isSettled = true;
                    return reject(new Error(`Invalid JSON passed to config --import: \n${error.message}.`));
                }
                if (settingsObj) {
                    // eslint-disable-next-line github/array-foreach -- Old code before rule was applied
                    Object.entries(settingsObj)
                        .forEach(([key, value]) => {
                        Setting_1.default.setValue(key, value);
                    });
                }
                if (!isSettled) {
                    isSettled = true;
                    resolve();
                }
            });
            inputStream.on('error', (error) => {
                if (!isSettled) {
                    isSettled = true;
                    reject(error);
                }
            });
        });
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
    async action(args) {
        const verbose = args.options.verbose;
        const isExport = args.options.export;
        const isImport = args.options.import || args.options.importFile;
        const importFile = args.options.importFile;
        const renderKeyValue = (name) => {
            const md = Setting_1.default.settingMetadata(name);
            let value = Setting_1.default.value(name);
            if (typeof value === 'object' || Array.isArray(value))
                value = JSON.stringify(value);
            if (md.secure && value)
                value = '********';
            if (Setting_1.default.isEnum(name)) {
                return (0, locale_1._)('%s = %s (%s)', name, value, Setting_1.default.enumOptionsDoc(name));
            }
            else {
                return (0, locale_1._)('%s = %s', name, value);
            }
        };
        if (isExport || (!isImport && !args.value)) {
            const keys = Setting_1.default.keys(!verbose, Setting_1.AppType.Cli);
            keys.sort();
            if (isExport) {
                // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
                const resultObj = keys.reduce((acc, key) => {
                    const value = Setting_1.default.value(key);
                    if (!verbose && !value)
                        return acc;
                    acc[key] = value;
                    return acc;
                }, {});
                // Printing the object in "pretty" format so it's easy to read/edit
                this.stdout(JSON.stringify(resultObj, null, 2));
            }
            else if (!args.name) {
                for (let i = 0; i < keys.length; i++) {
                    const value = Setting_1.default.value(keys[i]);
                    if (!verbose && !value)
                        continue;
                    this.stdout(renderKeyValue(keys[i]));
                }
            }
            else {
                this.stdout(renderKeyValue(args.name));
            }
            (0, app_1.default)().gui().showConsole();
            (0, app_1.default)().gui().maximizeConsole();
            return;
        }
        if (isImport) {
            let fileStream = process.stdin;
            if (importFile) {
                fileStream = fs.createReadStream(importFile, { autoClose: true });
            }
            await this.__importSettings(fileStream);
        }
        else {
            Setting_1.default.setValue(args.name, args.value);
        }
        if (args.name === 'locale') {
            (0, locale_1.setLocale)(Setting_1.default.value('locale'));
        }
        await Setting_1.default.saveAll();
    }
}
module.exports = Command;
//# sourceMappingURL=command-config.js.map