package com.workfusion.odf.impl.converter.extractor.mail;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger;

import com.workfusion.odf.impl.converter.extractor.AbstractRecursiveExtractor;
import com.workfusion.odf.impl.converter.extractor.DataWrapper;
import com.workfusion.odf.service.mail.EmailConstants;
import com.workfusion.odf.service.mail.entity.EmailAttachment;
import com.workfusion.odf.service.mail.entity.EmailMessage;
import com.workfusion.odf.service.mail.util.EmailParsingUtils;

public abstract class AbstractMailExtractor extends AbstractRecursiveExtractor {
	/**
	 * Constructor.
	 *
	 * @param logger
	 */
	public AbstractMailExtractor(final Logger logger) {
		super(logger);
	}

	protected abstract EmailMessage parseMessage(final InputStream contentIS, final String extension);

    protected List<DataWrapper> extract(final DataWrapper dataWrapper) {
        InputStream contentIS = new ByteArrayInputStream(dataWrapper.getData());
        String extension = FilenameUtils.getExtension(dataWrapper.getName()).toLowerCase();

        EmailMessage message = parseMessage(contentIS, extension);

        List<EmailAttachment> attachments = message.getAttachments();
        List<EmailAttachment> inlineFiles = message.getInlineFiles();

        // Message attachments
        List<DataWrapper> dataWrapperList = new ArrayList<>();
        if (attachments != null) {
        	for (EmailAttachment attachment : attachments) {
        		dataWrapperList.add(new DataWrapper(attachment.getContent(), attachment.getFileName(), EmailConstants.DOCTYPE_ATTACHMENT, null));
        	}
        }
        if (inlineFiles != null) {
        	for (EmailAttachment attachment : inlineFiles) {
        		dataWrapperList.add(new DataWrapper(attachment.getContent(), attachment.getFileName(), EmailConstants.DOCTYPE_INLINE_ATTACHMENT, null));
        	}
        }

        // Message body
        DataWrapper mailBody = extractBody(message);
        dataWrapperList.add(mailBody);

        return dataWrapperList;
    }

    private DataWrapper extractBody(final EmailMessage message) {
        String htmlBody = message.getHtml().orElseGet(() -> StringEscapeUtils.escapeHtml(message.getText()));
        byte[] data = htmlBody.getBytes(Charset.forName("UTF-8"));

        Map<String, String> attributes = new HashMap<>();
        if (message.getFrom() != null) {
            attributes.put("from", message.getFrom().toString());
        }
        if (message.getTo() != null) {
            attributes.put("to", EmailParsingUtils.emailsToString(message.getTo()));
        }
        if (message.getCc() != null) { 
            attributes.put("cc", EmailParsingUtils.emailsToString(message.getCc()));
        }
        attributes.put("subject", message.getSubject());

        return new DataWrapper(data, message.getSubject() + ".html", EmailConstants.DOCTYPE_MESSAGE, attributes);
    }
}
