'use strict';

const os = require('os');
const uuid = require('uuid');
const HTMLParser = require('node-html-parser');

function processDataUrl(element, useBase64) {
    let parts = (element.path || element.href).match(/^data:((?:[^;]*;)*(?:[^,]*)),(.*)$/i);
    if (!parts) {
        return element;
    }

    if (useBase64) {
        element.content = /\bbase64$/i.test(parts[1])
            ? Buffer.from(parts[2], 'base64').toString('base64')
            : Buffer.from(decodeURIComponent(parts[2])).toString('base64');
        element.encoding = 'base64';
    } else {
        element.content = /\bbase64$/i.test(parts[1]) ? Buffer.from(parts[2], 'base64') : Buffer.from(decodeURIComponent(parts[2]));
    }

    if ('path' in element) {
        delete element.path;
    }

    if ('href' in element) {
        delete element.href;
    }

    parts[1].split(';').forEach(item => {
        if (/^\w+\/[^/]+$/i.test(item)) {
            element.contentType = element.contentType || item.toLowerCase();
        }
    });

    return element;
}
function preprocessHtml(html, hostname) {
    if (Buffer.isBuffer(html)) {
        html = html.toString();
    }

    const root = HTMLParser.parse(html);
    let attachments = [];

    for (let img of root.getElementsByTagName('img')) {
        let src = img.getAttribute('src');
        if (/^data:/.test(src)) {
            try {
                let attachment = processDataUrl({ href: src }, true);
                if (attachment) {
                    let filename = img.getAttribute('data-filename');
                    if (filename) {
                        attachment.filename = filename;
                        img.removeAttribute('data-filename');
                    }
                    attachment.cid = `${uuid.v4()}@${hostname ? hostname : 'inline'}`;
                    img.setAttribute('src', `cid:${attachment.cid}`);

                    attachments.push(attachment);
                }
            } catch (err) {
                // should log?
                console.error(err);
            }
        }
    }

    return {
        html: attachments.length ? root.outerHTML : html,
        attachments
    };
}

function preprocessAttachments(data) {
    let hostname = data.from && data.from.address && typeof data.from.address === 'string' ? data.from.address.split('@').pop() : os.hostname();

    if (!data.html || !data.html.length || data.html.length > 12 * 1024 * 1024) {
        return;
    }

    try {
        let { html, attachments } = preprocessHtml(data.html, hostname);

        if (html) {
            data.html = html;
        }

        if (attachments && attachments.length) {
            data.attachments = [].concat(data.attachments || []).concat(attachments);
        }
    } catch (err) {
        // should log?
        console.error(err);
    }
}

module.exports = {
    processDataUrl,
    preprocessAttachments
};
