#include utility.js

const MamiSettingsBackup = function(settings) {
    const header = 'Mami Settings Export';
    const version = 1;
    const minVersion = 1;
    const maxVersion = 1;

    const exportData = () => {
        const names = settings.names();
        const data = { a: header, v: version, d: [] };

        for(const name of names) {
            const info = settings.info(name);
            if(info.immutable)
                continue;

            data.d.push({
                i: info.name,
                v: settings.get(info.name),
            });
        }

        return btoa(JSON.stringify(data));
    };

    const importData = (data, clear) => {
        try {
            data = JSON.parse(atob(data));
        } catch(ex) {
            throw 'Settings export data is invalid.';
        }

        if(typeof data !== 'object')
            throw 'Settings export data is not an object.';

        if(data.a !== header)
            throw 'Provided data is not settings export.';

        if(data.v < minVersion)
            throw 'Settings export is too old and no longer compatible with this version of the chat client.';
        if(data.v > maxVersion)
            throw 'Settings export is too new and not compatible with this version of the chat client.';

        if(!Array.isArray(data.d))
            throw 'Values are missing from settings export.';

        if(clear === true)
            settings.clear();

        let success = true;

        for(const exportInfo of data.d) {
            if(typeof exportInfo.i !== 'string')
                continue;

            try {
                settings.set(exportInfo.i, exportInfo.v);
            } catch(ex) {
                success = false;
            }
        }

        return success;
    };

    const importFile = file => {
        return new Promise((resolve, reject) => {
            const reader = new FileReader;
            reader.onerror = () => reject();
            reader.onload = () => {
                try {
                    resolve(importData(reader.result));
                } catch(ex) {
                    reject(ex);
                }
            };
            reader.readAsText(file);
        });
    };

    return {
        export: exportData,
        exportDownload: async (target, fileName) => {
            if(!(target instanceof Element))
                throw 'target must be an instance of Element';
            if(typeof fileName !== 'string')
                fileName = 'settings.mami';

            const data = exportData();
            const html = $e('a', {
                href: URL.createObjectURL(new Blob([data], { type: 'application/octet-stream' })),
                download: fileName,
                target: '_blank',
                style: { display: 'none' },
            });
            target.appendChild(html);
            html.click();
            target.removeChild(html);
        },
        import: importData,
        importFile: importFile,
        importUpload: (target) => {
            return new Promise((resolve, reject) => {
                const html = $e('input', {
                    type: 'file',
                    accept: '.mami',
                    style: { display: 'none' },
                });
                html.addEventListener('change', () => {
                    if(html.files.length > 0) {
                        importFile(html.files[0])
                            .then(result => resolve(result))
                            .catch(ex => reject(ex))
                            .finally(() => target.removeChild(html));
                    } else {
                        target.removeChild(html);
                        reject();
                    }
                });
                target.appendChild(html);
                html.click();
            });
        },
    };
};
