/* eslint-disable @typescript-eslint/no-explicit-any */
import { Config } from '@oclif/core';
import fsExtra from 'fs-extra';
import fs from 'node:fs';
import path from 'node:path';
import url from 'node:url';
export default class AppConfig {
    static instance;
    _CONFIG_FILE_NAME = 'config.json';
    appConfigDir;
    appConfigPath;
    cachedConfig;
    constructor(appConfigDir) {
        this.appConfigDir = appConfigDir;
        this.appConfigPath = path.join(appConfigDir, this._CONFIG_FILE_NAME);
        this.cachedConfig = this.ingestConfig();
    }
    static async getInstance() {
        if (!AppConfig.instance) {
            const appConfigDir = await this.prepareAppConfigDir();
            AppConfig.instance = new AppConfig(appConfigDir);
        }
        return AppConfig.instance;
    }
    static async prepareAppConfigDir() {
        const __filename = url.fileURLToPath(import.meta.url);
        const __dirname = path.dirname(__filename);
        const root = path.resolve(__dirname, '..');
        const config = await Config.load({ root });
        const { configDir } = config;
        fs.mkdirSync(configDir, { recursive: true });
        return configDir;
    }
    flushConfig() {
        fsExtra.writeJSONSync(this.appConfigPath, this.cachedConfig);
    }
    getConfig(key, scope) {
        return this.getFullConfig(scope)[key];
    }
    getConfigDir() {
        return this.appConfigDir;
    }
    getConfigFilePath(filename) {
        return path.join(this.appConfigDir, filename);
    }
    getFullConfig(scope) {
        return (scope ? this.cachedConfig[scope] : this.cachedConfig) || {};
    }
    ingestConfig() {
        return fsExtra.readJSONSync(this.appConfigPath, { throws: false }) || {};
    }
    readConfigFile(filename) {
        const filePath = path.join(this.appConfigDir, filename);
        if (fs.existsSync(filePath)) {
            return fs.readFileSync(filePath, 'utf8');
        }
        return undefined;
    }
    setConfig(name, value, scope) {
        if (scope) {
            this.cachedConfig[scope] = this.cachedConfig[scope] || {};
            this.cachedConfig[scope][name] = value;
        }
        else {
            this.cachedConfig[name] = value;
        }
        this.flushConfig();
    }
    writeConfigFile(filename, content, mode) {
        const filePath = path.join(this.appConfigDir, filename);
        if (content === undefined) {
            if (fs.existsSync(filePath)) {
                fs.unlinkSync(filePath);
            }
            return;
        }
        fs.writeFileSync(filePath, content, { encoding: 'utf8' });
        if (mode) {
            fs.chmodSync(filePath, mode);
        }
    }
}
