/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hu.nir.nmail.spring.controllers;

import hu.nir.nmail.ejb.entity.NmailUser;
import hu.nir.nmail.ejb.entity.UserRestriction;
import hu.nir.nmail.services.DownloadMailService;
import hu.nir.nmail.services.SendMessageService;
import hu.nir.nmail.spring.beans.MailsData;
import hu.nir.nmail.spring.beans.NmailErrors;
import hu.nir.nmail.utils.NmailUtility;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.MessagingException;
import javax.mail.Address;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

/**
 *
 * @author Fodor Attila
 */
public class SendMessageController extends SimpleFormController {
    private SendMessageService sendMessageService;
    private DownloadMailService downloadMailService;
    private String logoutView;
    private String errorView;
    private HttpSession session;
    private Logger log = Logger.getLogger(SendMessageController.class.getName());
    private NmailErrors nmailErrors;
    private Boolean test = new Boolean(false);
    
    @Override
    protected ModelAndView onSubmit(Object command, BindException errors) {

        MailsData mailsData = (MailsData) command;
        NmailUser nmailUser = (NmailUser) session.getAttribute("nmailUser");

        if (nmailErrors != null) {
            return new ModelAndView(getErrorView(), "nmailErrors", nmailErrors);
        }

        if (mailsData == null || nmailUser == null) {
            log.log(Level.INFO, "Return to login because session timed out.");
            return new ModelAndView(getLogoutView());
        }
        
        if (test && !validateTestAddresses(mailsData.getTestAddresses())) {
            nmailErrors = new NmailErrors();
            nmailErrors.addErrorCode("error.testaddresses");
            return new ModelAndView(getFormView(),NmailUtility.toMap("mailsData", mailsData, "nmailErrors", nmailErrors));
        }
        
        Map<String, Object> result = null;
            
        try {
            result = sendMessageService.processCommand(mailsData, nmailUser, test);
        } catch (MessagingException ex) {
            log.log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            log.log(Level.SEVERE, null, ex);
        }

        if (result == null) {
            log.log(Level.INFO, "Return to login because session timed out.");
            return new ModelAndView(getLogoutView());
        }

        mailsData = (MailsData) result.get("mailsData");

        if (mailsData == null) {
            log.log(Level.INFO, "Return to login because session timed out.");
            return new ModelAndView(getLogoutView());
        }
        
        Map<String,Object> model = (Map<String, Object>) downloadMailService.processCommand(nmailUser,mailsData);
        if (model == null) {
            return new ModelAndView(getLogoutView());
        }
        model = NmailUtility.mergeMaps(model, result);
        session.setAttribute("mailsData", model.get("mailsData"));

        return new ModelAndView(getSuccessView(), model);
        
    }
    
    @Override
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
        session = request.getSession();
        MailsData mailsData = (MailsData) session.getAttribute("mailsData");
        NmailUser nmailUser = (NmailUser) session.getAttribute("nmailUser");
        
        if (mailsData == null || nmailUser == null) {
            return super.formBackingObject(request);
        }
        
        UserRestriction userRoles = nmailUser.getUserRestriction();
        
        if (userRoles == null) {
            nmailErrors = new NmailErrors();
            nmailErrors.addFatalErrorCode("fatalerror.nouserroles");
            log.log(Level.INFO, "UserRoles not found for this user: "+nmailUser.getNmailUserLogin().getUserName());
            return super.formBackingObject(request);
        }
        
        String messageIndex = request.getParameter("messageIndex");
        
        if (messageIndex != null) {
            mailsData.setMessageIndex(Integer.parseInt(messageIndex));
        }
        
        String senderAddress = request.getParameter("senderAddress");
        String senderName = request.getParameter("senderName");
        String subject = request.getParameter("subject");
        String testAddresses = request.getParameter("testAddresses");
        
        if (userRoles.getAbleToSetSender()) {
            mailsData.setSenderAddress(senderAddress);
            mailsData.setSenderName(senderName);
        }
        
        mailsData.setSubject(subject);
        mailsData.setTestAddresses(testAddresses);
        
        String testStr = request.getParameter("test");
        if (testStr != null) {
            test = true;
        }
        
        return mailsData;
    }
    
    private boolean validateTestAddresses(String testAddresses) {
        if (!StringUtils.hasText(testAddresses)) {
            return false;
        }
        
        StringTokenizer tokenizer = new StringTokenizer(testAddresses,",");
        
        while (tokenizer.hasMoreTokens()) {
            String addressStr = tokenizer.nextToken();
            try {
                Address address = new InternetAddress(addressStr.trim());
            } catch (AddressException ex) {
                continue;
            }
            return true;
        }
        
        return false;
    }

    public SendMessageService getSendMessageService() {
        return sendMessageService;
    }

    public void setSendMessageService(SendMessageService sendMessageService) {
        this.sendMessageService = sendMessageService;
    }

    public String getLogoutView() {
        return logoutView;
    }

    public void setLogoutView(String logoutView) {
        this.logoutView = logoutView;
    }

    public String getErrorView() {
        return errorView;
    }

    public void setErrorView(String errorView) {
        this.errorView = errorView;
    }

    public DownloadMailService getDownloadMailService() {
        return downloadMailService;
    }

    public void setDownloadMailService(DownloadMailService downloadMailService) {
        this.downloadMailService = downloadMailService;
    }
}
