package ru.yandex.wmtools.common.service;

import java.io.UnsupportedEncodingException;
import java.util.Collection;

import javax.mail.Header;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMailMessage;
import org.springframework.mail.javamail.MimeMessageHelper;

import ru.yandex.common.util.collections.CollectionFactory;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.InternalProblem;
import ru.yandex.wmtools.common.util.Md5Util;

/**
 * User: baton
 * Date: 28.06.2007
 * Time: 20:56:09
 */
public class MailService implements IService {
    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final String X_YANDEX_SERVICE_SALT = "76336c7a96b13f0258054d239e70fec8";

    private JavaMailSender mailSender;

    public interface AttachmentData {
        String getName();

        InputStreamSource getData();
    }

    public void sendWithAttachments(final String subject, final String content,
                                    final String[] to, final String[] bcc, final String fromName,
                                    final String fromEmail, final AttachmentData[] attachments, Header... headers) throws
            MessagingException, UnsupportedEncodingException, InternalException {
        MimeMessage message = mailSender.createMimeMessage();

        MimeMessageHelper helper = new MimeMessageHelper(message, true, DEFAULT_CHARSET);

        helper.setTo(to);

        if (bcc != null && bcc.length > 0) {
            helper.setBcc(bcc);
        }

        helper.setFrom(fromEmail, fromName);

        helper.setSubject(subject);

        helper.setText(content);

        if (attachments != null) {
            for (AttachmentData attachment : attachments) {
                helper.addAttachment(attachment.getName(), attachment.getData());
            }
        }

        MimeMailMessage mimeMailMessage = new MimeMailMessage(message);

        for (Header header : headers) {
            mimeMailMessage.getMimeMessage().addHeader(header.getName(), header.getValue());
        }

        try {
            mailSender.send(mimeMailMessage.getMimeMessage());
        } catch (MailException e) {
            throw new InternalException(InternalProblem.MAIL_SEND_FAILURE, e.getMessage(), e);
        }
    }

    /**
     * Вычисляет значение заголовка X-Yandex-Service для Я.Почты.
     * NOTE! Параметры передаются в незакодированном виде
     *
     * @param date        незакодированное значение заголовка Date
     * @param from        незакодированное значение заголовка From
     * @param subject     незакодированное значение заголовка Subject
     * @param yandexLabel метка сервиса, например, yawebmaster, yasitesearch или yaxml.
     * @return значение заголовка X-Yandex-Service
     */
    public String getYandexServiceHeaderValue(String date, String from, String subject, String yandexLabel) {
        final Collection<String> items = CollectionFactory.list(date, from, subject, yandexLabel, X_YANDEX_SERVICE_SALT);
        final String line = StringUtils.join(items, "_");
        final String md5 = Md5Util.getMd5(line);
        final String serviceLine = yandexLabel + " " + md5;
        final Base64 base64 = new Base64(0);
        return new String(base64.encode(serviceLine.getBytes()));
    }

    public JavaMailSender getMailSender() {
        return mailSender;
    }

    @Required
    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }
}
