const fs = require('fs');
const path = require('path');
const config = require('./config');
const Component = require('./component');
const Cluster = require('./cluster');

if (!process.env.OPENSSL_CONF)
    process.env.OPENSSL_CONF = '/etc/ssl/';

class Report extends Component {
    constructor(name, args) {
        super(name);

        this.args = args;
    }

    get path() {
        return `../templates/reports/${this.name}`;
    }

    async getName() {
        return (await this.getUserLocale())['reportName'];
    }

    async toPdfStream() {
        const template = await this.render();
        const defaultOptions = Object.assign({}, config.pdf);

        const optionsPath = `${this.path}/options.json`;
        const fullPath = path.resolve(__dirname, optionsPath);
        let options = defaultOptions;
        if (fs.existsSync(fullPath))
            options = require(optionsPath);

        return new Promise((resolve, reject) => {
            Cluster.pool.queue({}, async({page}) => {
                try {
                    await page.emulateMediaType('screen');
                    await page.setContent(template);

                    const element = await page.$('#pageFooter');

                    let footer = '\n';
                    if (element) {
                        footer = await page.evaluate(el => {
                            const html = el.innerHTML;
                            el.remove();
                            return html;
                        }, element);
                    }

                    options.headerTemplate = '\n';
                    options.footerTemplate = footer;

                    const buffer = await page.pdf(options);
                    resolve(buffer);
                } catch (err) {
                    reject(err);
                }
            });
        });
    }

    /**
     * Returns all the params that ends with id
     *
     * @return {array} List of identifiers
     */
    getIdentifiers() {
        const identifiers = [];
        const args = this.args;
        const keys = Object.keys(args);

        for (let arg of keys) {
            if (arg.endsWith('Id'))
                identifiers.push(arg);
        }

        return identifiers;
    }

    async getFileName() {
        const args = this.args;
        const identifiers = this.getIdentifiers(args);
        const name = await this.getName();
        const params = [];
        params.push(name);

        for (let id of identifiers)
            params.push(args[id]);

        const fileName = params.join('_');

        return `${fileName}.pdf`;
    }
}

module.exports = Report;