import { dirname } from 'node:path';
import { parse, stringify } from 'yaml';

export const createProfile = () => ({
    server_url: '',
    apptid: '',
    token: {
        access_token: ''
    }
});

export const createConfig = (profile = 'default') => ({
    active_profile: profile,
    profiles: {
        [profile]: createProfile()
    },
    plugins: []
});

export const load = async (path, { fs, console, createIfNotExists = true }) => {
    const withSave = (config) => {
        const configWithSave = Object.assign(Object.create({
            save: async () => {
                console.debug('Saving configuration to file \'%s\'', path);
                try {
                    await fs.mkdir(dirname(path), { recursive: true });
                    await fs.writeFile(path, stringify(configWithSave));
                    return true;
                } catch(err) {
                    console.debug('Failed to save configuration to file \'%s\'', path);
                    throw err;
                }
            }
        }, {
            path: {
                value: path
            }
        }), config);
        return configWithSave;
    };

    console.debug('Loading configuration from file \'%s\'', path);
    try {
        const config = parse(await fs.readFile(path, { encoding: 'utf-8' }));
        return withSave(config);
    } catch(err) {
        console.debug('Failed to read configuration file \'%s\'', path);
        if (createIfNotExists && (err?.code === 'ENOENT')) {
            console.debug('Creating new configuration file \'%s\'', path);
            const config = createConfig();
            await fs.mkdir(dirname(path), { recursive: true });
            await fs.writeFile(path, stringify(config), { mode: 0o600 });
            return withSave(config);
        }
        throw err;
    }
};
