package gov.va.vinci.dart.mail.mock;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

import javax.mail.Message.RecipientType;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.mail.javamail.MimeMessageHelper;

import gov.va.vinci.dart.mail.MailManager;
import gov.va.vinci.dart.mail.MailManagerImpl;
import gov.va.vinci.dart.service.DartObjectFactory;
import gov.va.vinci.dart.usr.UserManager;
import gov.va.vinci.security.userdetails.UserDetails;

public class MailManagerMock implements MailManager {
	@Autowired(required=false)
	private String smtpHost;
	
	@Autowired(required=false)
	private String fromAddr;
	
	@Autowired(required=false)
	private boolean capture = false;
	
	@Autowired(required=false)
	private String copyAllAddr;

	private MailManagerImpl realMailManager;
	
	private List<MimeMessage> messages = new ArrayList<MimeMessage>();
	private HashMap<String,String> EMAIL_CACHE = new HashMap<String,String>();

	public void setSmtpHost(final String hostname) {
		smtpHost = hostname;
	}

	public void setFromAddr(final String addr) {
		fromAddr = addr;
	}

	public void setCopyAllAddr(final String addr) {
		copyAllAddr = addr;
		realMailManager = new MailManagerImpl();
		realMailManager.setSmtpHost(smtpHost);
		realMailManager.setFromAddr(fromAddr);
	}

	public void setCapture(final String capture) {
		this.capture = Boolean.parseBoolean(capture);
	}

	public void setCapture(final boolean capture) {
		this.capture = capture;
	}

	public void sendPlainMail(final String userLoginId, final String subject, final String text) {
		try {
			sendPlainMail1(userLoginId, subject, text);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void sendPlainMailToEmailDest(final String recipient, final String subject, final String text) {
		try {
			sendPlainMail0(recipient, subject, text);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendPlainMail1(final String userLoginId, final String subject, final String text) throws Exception {
		// get the user email address out of Active Directory
		
		String emailDest = EMAIL_CACHE.get(userLoginId);
		
		if (emailDest == null) {
			
			try {
				UserManager userManager = DartObjectFactory.getInstance().getUserManager();
			
				UserDetails userDetails = userManager.getUserDetails(userLoginId);
				
				emailDest = userDetails.getEmailAddress();
				EMAIL_CACHE.put(userLoginId, emailDest);
			} catch (Exception e) {
				return;
			}
		}

		sendPlainMail0(emailDest, subject, text);
	}
	
	public void sendPlainMail0(final String emailDest, final String subject, final String text) throws Exception {

		if (copyAllAddr != null) {
			System.err.println("mock email manager forwarding email to " + copyAllAddr);
			realMailManager.sendPlainMail1(copyAllAddr, subject, text);
		}

		if (capture == false) {
			return;
		}
		
		Properties props = new Properties();
		Session session = Session.getInstance(props);
				
		MimeMessage msg = new MimeMessage(session);
		msg.setRecipient(RecipientType.TO, new InternetAddress(emailDest));

		String subjectWithoutNewlines = subject.replaceAll("(?:\\n|\\r)", " ");
		msg.setSubject(subjectWithoutNewlines);

		msg.setText(text);
		
		messages.add(msg);
	}
	
	
	public void sendHTMLMail(final String userLoginId, final String subject, final String text, final boolean bIncludePrefix) {
		try {
			sendHTMLMail1(userLoginId, subject, text);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendHTMLMailToEmailDest(final String recipient, final String subject, final String text, final boolean bIncludePrefix) {
		try {
			sendHTMLMail0(recipient, subject, text);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendHTMLMail1(final String userLoginId, final String subject, final String text) throws Exception {
		// get the user email address out of Active Directory
		
		String emailDest = EMAIL_CACHE.get(userLoginId);
		
		if (emailDest == null) {
			
			try {
				UserManager userManager = DartObjectFactory.getInstance().getUserManager();
			
				UserDetails userDetails = userManager.getUserDetails(userLoginId);
				
				emailDest = userDetails.getEmailAddress();
				EMAIL_CACHE.put(userLoginId, emailDest);
			} catch (Exception e) {
				return;
			}
		}

		sendHTMLMail0(emailDest, subject, text);
	}
	
	public void sendHTMLMail0(final String emailDest, final String subject, final String text) throws Exception {

		if (copyAllAddr != null) {
			System.err.println("mock email manager forwarding email to " + copyAllAddr);
			realMailManager.sendHTMLMail1(copyAllAddr, subject, text);
		}

		if (capture == false) {
			return;
		}
		
		Properties props = new Properties();
		Session session = Session.getInstance(props);
				
		MimeMessage msg = new MimeMessage(session);
		msg.setRecipient(RecipientType.TO, new InternetAddress(emailDest));
		msg.setSubject(subject);
		msg.setText(text, "UTF-8", "html");	//text/html
		
		messages.add(msg);
	}
	


	public void sendPlainAndHTMLMail(final String userLoginId, final String subject, final String plainBody, final String htmlBody, final boolean bIncludePrefix) {
		try {
			sendPlainAndHTMLMail1(userLoginId, subject, plainBody, htmlBody);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendPlainAndHTMLMailToEmailDest(final String recipient, final String subject, final String plainBody, final String htmlBody, final boolean bIncludePrefix) {
		try {
			sendPlainAndHTMLMail0(recipient, subject, plainBody, htmlBody);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendPlainAndHTMLMail1(final String userLoginId, final String subject, final String plainBody, final String htmlBody) throws Exception {
		// get the user email address out of Active Directory
		
		String emailDest = EMAIL_CACHE.get(userLoginId);
		
		if (emailDest == null) {
			
			try {
				UserManager userManager = DartObjectFactory.getInstance().getUserManager();
			
				UserDetails userDetails = userManager.getUserDetails(userLoginId);
				
				emailDest = userDetails.getEmailAddress();
				EMAIL_CACHE.put(userLoginId, emailDest);
			} catch (Exception e) {
				return;
			}
		}

		sendPlainAndHTMLMail0(emailDest, subject, plainBody, htmlBody);
	}
	
	public void sendPlainAndHTMLMail0(final String emailDest, final String subject, final String plainBody, final String htmlBody) throws Exception {

		if (copyAllAddr != null) {
			System.err.println("mock email manager forwarding email to " + copyAllAddr);
			realMailManager.sendPlainAndHTMLMail1(copyAllAddr, subject, plainBody, htmlBody);
		}

		if (capture == false) {
			return;
		}
		
		Properties props = new Properties();
		Session session = Session.getInstance(props);
				
		MimeMessage msg = new MimeMessage(session);
		msg.setRecipient(RecipientType.TO, new InternetAddress(emailDest));
		msg.setSubject(subject);
		

		//
		// Set the content for each type

        // plain text version
        final MimeBodyPart textPart = new MimeBodyPart();
        textPart.setContent(plainBody, "text/plain"); 

        // HTML version
        final MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(htmlBody, "text/html");

        // Create the multipart.  Add HTML and plain text BodyParts to it.
        final Multipart multipart = new MimeMultipart("alternative");
        multipart.addBodyPart(textPart);
        multipart.addBodyPart(htmlPart);

        // Set Multipart as the message's content
        msg.setContent(multipart);
		
		
		messages.add(msg);
	}
	
	

	public void sendPlainAndHTMLMailWithAttachment(final String userLoginId, final String subject, final String plainBody, final String htmlBody, final boolean bIncludePrefix, final String attachmentFilename) {
		try {
			sendPlainAndHTMLMailWithAttachment1(userLoginId, subject, plainBody, htmlBody, attachmentFilename);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendPlainAndHTMLMailWithAttachmentToEmailDest(final String recipient, final String subject, final String plainBody, final String htmlBody, final boolean bIncludePrefix, final String attachmentFilename) {
		try {
			sendPlainAndHTMLMailWithAttachment0(recipient, subject, plainBody, htmlBody, attachmentFilename);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void sendPlainAndHTMLMailWithAttachment1(final String userLoginId, final String subject, final String plainBody, final String htmlBody, final String attachmentFilename) throws Exception {
		// get the user email address out of Active Directory
		
		String emailDest = EMAIL_CACHE.get(userLoginId);
		
		if (emailDest == null) {
			
			try {
				UserManager userManager = DartObjectFactory.getInstance().getUserManager();
			
				UserDetails userDetails = userManager.getUserDetails(userLoginId);
				
				emailDest = userDetails.getEmailAddress();
				EMAIL_CACHE.put(userLoginId, emailDest);
			} catch (Exception e) {
				return;
			}
		}

		sendPlainAndHTMLMailWithAttachment0(emailDest, subject, plainBody, htmlBody, attachmentFilename);
	}
	
	public void sendPlainAndHTMLMailWithAttachment0(final String emailDest, final String subject, final String plainBody, final String htmlBody, final String attachmentFilename) throws Exception {

		if (copyAllAddr != null) {
			System.err.println("mock email manager forwarding email to " + copyAllAddr);
			realMailManager.sendPlainAndHTMLMailWithAttachment1(copyAllAddr, subject, plainBody, htmlBody, attachmentFilename);
		}

		if (capture == false) {
			return;
		}
		
		Properties props = new Properties();
		Session session = Session.getInstance(props);
				
		MimeMessage msg = new MimeMessage(session);
		
		MimeMessageHelper helper = new MimeMessageHelper(msg, true);	//multi-part message
		
		
		// Set the RFC 822 "From" header field using the
		// value of the InternetAddress.getLocalAddress method.
		helper.setFrom(new InternetAddress(fromAddr));
	
		// Add the given addresses to the specified recipient type.
		helper.setTo(new InternetAddress(emailDest));
	
		// Set the "Subject" header field.
		helper.setSubject(subject);
	

		// Set the multi-part message content
        helper.setText(plainBody, htmlBody);


//        //add the attachment
//        Resource attachmentResource = DartObjectFactory.getInstance().getApplicationContext().getResource("/WEB-INF/classes/" + attachmentFilename);
//        if( attachmentResource != null ) {
//        	helper.addAttachment(attachmentFilename, attachmentResource.getFile());
//        }//end if

		
		messages.add(msg);
	}
	
	
	
	public List<MimeMessage> getMessages() {
		return messages;
	}
	
	public void clearCaptureList() {
		messages.clear();
	}
	
	public void sendTLSMail() {
		
	}
}
