import kdbxweb from 'kdbxweb';
import { Events } from 'framework/events';
import { SettingsStore } from 'comp/settings/settings-store';
import { Links } from 'const/links';
import { SignatureVerifier } from 'util/data/signature-verifier';
import { Logger } from 'util/logger';

const PluginGallery = {
    logger: new Logger('plugin-gallery'),

    gallery: null,
    loading: false,
    loadError: null,

    loadPlugins() {
        if (this.gallery) {
            return Promise.resolve(this.gallery);
        }
        this.loading = true;
        this.loadError = false;
        const ts = this.logger.ts();
        return new Promise(resolve => {
            this.logger.debug('Loading plugins...');
            const xhr = new XMLHttpRequest();
            xhr.open('GET', Links.Plugins + '/plugins.json?_=' + Date.now());
            xhr.responseType = 'json';
            xhr.send();
            xhr.addEventListener('load', () => {
                const data = xhr.response;
                resolve(data);
            });
            xhr.addEventListener('error', () => {
                this.logger.error('Network error loading plugins');
                resolve();
            });
        })
            .then(data => {
                this.loading = false;
                if (!data) {
                    this.loadError = true;
                    Events.emit('plugin-gallery-load-complete');
                    return;
                }
                return this.verifySignature(data).then(gallery => {
                    this.loadError = !gallery;
                    if (gallery) {
                        this.logger.debug(
                            `Loaded ${gallery.plugins.length} plugins`,
                            this.logger.ts(ts)
                        );
                        this.gallery = gallery;
                        this.saveGallery(gallery);
                    }
                    Events.emit('plugin-gallery-load-complete');
                    return gallery;
                });
            })
            .catch(e => {
                this.loadError = true;
                this.logger.error('Error loading plugin gallery', e);
                Events.emit('plugin-gallery-load-complete');
            });
    },

    verifySignature(gallery) {
        const dataToVerify = JSON.stringify(gallery, null, 2).replace(gallery.signature, '');
        return SignatureVerifier.verify(
            kdbxweb.ByteUtils.stringToBytes(dataToVerify),
            gallery.signature
        )
            .then(isValid => {
                if (isValid) {
                    return gallery;
                }
                this.logger.error('JSON signature invalid');
            })
            .catch(e => {
                this.logger.error('Error verifying plugins signature', e);
            });
    },

    getCachedGallery() {
        const ts = this.logger.ts();
        return SettingsStore.load('plugin-gallery').then(data => {
            if (data) {
                return this.verifySignature(data).then(gallery => {
                    this.logger.debug(`Loaded cached plugin gallery`, this.logger.ts(ts));
                    return gallery;
                });
            }
        });
    },

    saveGallery(data) {
        SettingsStore.save('plugin-gallery', data);
    }
};

export { PluginGallery };
