"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigManager = exports.ShellHomeDirectory = void 0;
exports.getStoragePaths = getStoragePaths;
exports.getGlobalConfigPaths = getGlobalConfigPaths;
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const events_1 = require("events");
const bson_1 = require("bson");
class ShellHomeDirectory {
    constructor(paths) {
        this.ensureExistsPromise = null;
        this.paths = paths;
    }
    async ensureExists() {
        this.ensureExistsPromise ??= (async () => {
            await fs_1.promises.mkdir(this.paths.shellRoamingDataPath, {
                recursive: true,
                mode: 0o700,
            });
            await fs_1.promises.mkdir(this.paths.shellLocalDataPath, {
                recursive: true,
                mode: 0o700,
            });
        })();
        return this.ensureExistsPromise;
    }
    roamingPath(subpath) {
        return path_1.default.join(this.paths.shellRoamingDataPath, subpath);
    }
    localPath(subpath) {
        return path_1.default.join(this.paths.shellLocalDataPath, subpath);
    }
    rcPath(subpath) {
        return path_1.default.join(this.paths.shellRcPath, subpath);
    }
}
exports.ShellHomeDirectory = ShellHomeDirectory;
class ConfigManager extends events_1.EventEmitter {
    constructor(shellHomeDirectory) {
        super();
        this.shellHomeDirectory = shellHomeDirectory;
        this.config = null;
    }
    path() {
        return this.shellHomeDirectory.roamingPath('config');
    }
    async generateOrReadConfig(defaultConfig) {
        await this.shellHomeDirectory.ensureExists();
        let fd;
        try {
            try {
                fd = await fs_1.promises.open(this.path(), 'r');
            }
            catch (err) {
                if (err?.code !== 'ENOENT') {
                    this.emit('error', err);
                    throw err;
                }
            }
            if (fd !== undefined) {
                try {
                    const config = bson_1.EJSON.parse(await fd.readFile({ encoding: 'utf8' }));
                    this.emit('update-config', config);
                    return { ...defaultConfig, ...config };
                }
                catch (err) {
                    this.emit('error', err);
                    return defaultConfig;
                }
            }
            else {
                await this.writeConfigFile(defaultConfig);
                this.emit('new-config', defaultConfig);
                return defaultConfig;
            }
        }
        finally {
            await fd?.close();
        }
    }
    async writeConfigFile(config) {
        await this.shellHomeDirectory.ensureExists();
        try {
            await fs_1.promises.writeFile(this.path(), bson_1.EJSON.stringify(config), { mode: 0o600 });
        }
        catch (err) {
            this.emit('error', err);
            throw err;
        }
    }
}
exports.ConfigManager = ConfigManager;
function getStoragePaths() {
    let shellLocalDataPath;
    let shellRoamingDataPath;
    if (process.platform === 'win32') {
        const appData = process.env.APPDATA;
        const localAppData = process.env.LOCALAPPDATA ?? process.env.APPDATA;
        if (localAppData && appData) {
            shellLocalDataPath = path_1.default.join(localAppData, 'mongodb', 'mongosh');
            shellRoamingDataPath = path_1.default.join(appData, 'mongodb', 'mongosh');
        }
    }
    const homedir = path_1.default.join(os_1.default.homedir(), '.mongodb', 'mongosh');
    shellLocalDataPath ??= homedir;
    shellRoamingDataPath ??= homedir;
    return {
        shellLocalDataPath,
        shellRoamingDataPath,
        shellRcPath: os_1.default.homedir(),
    };
}
function getGlobalConfigPaths() {
    const paths = [];
    if (process.env.MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING) {
        paths.push(process.env.MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING);
    }
    switch (process.platform) {
        case 'win32':
            if (process.execPath === process.argv[1]) {
                paths.push(path_1.default.resolve(process.execPath, '..', 'mongosh.cfg'));
            }
            return paths;
        case 'darwin':
            paths.push('/usr/local/etc/mongosh.conf');
            paths.push('/opt/homebrew/etc/mongosh.conf');
        default:
            paths.push('/etc/mongosh.conf');
            return paths;
    }
}
//# sourceMappingURL=config-directory.js.map