package com.cftech.cms.SendEmail;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import com.cftech.core.util.SystemConfig;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * 实现邮件发送功能
 * @author Jasper Huang
 *
 */
public class EmailSenderWithAttach {
	private static final Logger logger = LogManager.getLogger(EmailSenderWithAttach.class);

	private String host; // 服务器地址

	private String from; // 发件人

	private String to; // 收件人 多个收件人以,分隔

	private String title; // 主题

	private String content; // 内容

	private List<File> attachmentlist ; //附件集

	private String username; // 用户名

	private String password; // 密码

	private String fileName;  //附件名

	private List<String> fileNames;//附件名
	/**发件人员工编号*/
	private String sendEmployeeId;

	private String cc;

	public String getCc() {
		return cc;
	}

	public void setCc(String cc) {
		this.cc = cc;
	}

	public String getSendEmployeeId() {
		return sendEmployeeId;
	}
	public void setSendEmployeeId(String sendEmployeeId) {
		this.sendEmployeeId = sendEmployeeId;
	}
	public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public String getFrom() {
		return from;
	}
	public void setFrom(String from) {
		this.from = from;
	}
	public String getTo() {
		return to;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public List<File> getAttachmentlist() {
		return attachmentlist;
	}
	public void setAttachmentlist(List<File> attachmentlist) {
		this.attachmentlist = attachmentlist;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getPort() {
		return port;
	}
	public void setPort(String port) {
		this.port = port;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public List<String> getFileNames(){ return fileNames;}

	public void setFileNames(List<String> fileNames){
	    this.fileNames=fileNames;
    }

	private String port;

	public EmailSenderWithAttach(String host, String from, String to, String title,
								  String content, List attachmentlist, String username, String password,String port,String fileName) {
		this.host = host;
		this.from = from;
		this.to = to;
		this.title = title;
		this.content = content;
		this.attachmentlist = attachmentlist;
		this.username = username;
		this.password = password;
		this.port=port;
		this.fileName=fileName;
	}

	public EmailSenderWithAttach(String host, String from, String to,String cc, String title,
								 String content, List attachmentlist, String username, String password,String port,String fileName) {
		this.host = host;
		this.from = from;
		this.to = to;
		this.title = title;
		this.content = content;
		this.attachmentlist = attachmentlist;
		this.username = username;
		this.password = password;
		this.port=port;
		this.fileName=fileName;
		this.cc = cc;
	}

	public EmailSenderWithAttach(String host, String from, String to,String cc, String title,
								 String content, List attachmentlist, String username, String password,String port,List<String> fileNames) {
		this.host = host;
		this.from = from;
		this.to = to;
		this.title = title;
		this.content = content;
		this.attachmentlist = attachmentlist;
		this.username = username;
		this.password = password;
		this.port=port;
		this.fileNames=fileNames;
		this.cc = cc;
	}

	public EmailSenderWithAttach(String to, String title,
			String content, List attachmentlist) {
		this.to = to;
		this.title = title;
		this.content = content;
		this.attachmentlist = attachmentlist;
	}

	/**
	 * 发送邮件
	 * @return 发送状态信息 index0：状态 0成功 1失败;index1：描述错误信息
	 */
	public String[] sendMail(){
		String[] result=new String[2];

		Session session=null;
		Properties props = System.getProperties();

		final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
		props.setProperty("mail.smtp.host", host);
		props.setProperty("mail.smtp.auth", "true");
		props.setProperty("mail.smtp.user", username);
		props.setProperty("mail.smtp.pass", password);

		props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
		props.setProperty("mail.smtp.socketFactory.fallback", "false");
		//邮箱发送服务器端口,这里设置为465端口
		props.setProperty("mail.smtp.port", "465");
		props.setProperty("mail.smtp.socketFactory.port", "465");

//		props.put("mail.smtp.host", props);
//		props.put("mail.smtp.sendpartial", "true");
//		props.put("mail.smtp.port", port);

		if(StringUtils.isBlank(username)){//不需要验证用户名密码
			session = Session.getDefaultInstance(props, null);
		}else{
			props.put("mail.smtp.auth", "true");
			EmailAuthenticator auth = new EmailAuthenticator(username, password);
			session = Session.getInstance(props, auth);
		}

		//设置邮件发送信息
		try{
			// 创建邮件
			MimeMessage message = new MimeMessage(session);
			// 自定义昵称
			String nick = SystemConfig.p.getProperty("nickname");
			if(com.cftech.core.util.StringUtils.isNotBlank(nick)){
				nick=javax.mail.internet.MimeUtility.encodeText(nick);
				message.setFrom(new InternetAddress(nick+" <"+from+">"));
			}else{
				message.setFrom(new InternetAddress(from));
			}

			// 设置收件人地址（多个邮件地址）
			InternetAddress[] toAddr = InternetAddress.parse(to);
			message.addRecipients(Message.RecipientType.TO, toAddr);
			//抄送人
			if(StringUtils.isNotBlank(cc)){
				InternetAddress[] toAddrCC = InternetAddress.parse(cc);
				message.addRecipients(Message.RecipientType.CC, toAddrCC);
			}

			// 设置邮件主题
			message.setSubject(title);

			// 设置发送时间
			message.setSentDate(new Date());
			// 设置发送内容
			Multipart multipart = new MimeMultipart();
			MimeBodyPart contentPart = new MimeBodyPart();
//			contentPart.setText(content);

			contentPart.setContent(content,"text/html;charset=gb2312");

			multipart.addBodyPart(contentPart);
			//设置附件
			if(attachmentlist!=null && attachmentlist.size()>0){
				for(int i = 0 ; i < attachmentlist.size();i++){
					MimeBodyPart attachmentPart = new MimeBodyPart();

					FileDataSource source = new FileDataSource(attachmentlist.get(i));
					attachmentPart.setDataHandler(new DataHandler(source));
					attachmentPart.setFileName(MimeUtility.encodeWord(fileName, "gb2312", null));
					multipart.addBodyPart(attachmentPart);
				}
			}
//			message.setContent(content,"text/html;charset=gb2312");
			message.setContent(multipart);
			//登录SMTP服务器
			if (StringUtils.isBlank(username)) {
				// 不需验证
				Transport.send(message);
			} else {
				// 需要验证
				Transport transport = session.getTransport("smtp");
				transport.connect();
				transport.sendMessage(message, message.getAllRecipients());
				transport.close();
			}

			result[0]="0";
			result[1]="发送成功";

			logger.info("邮件发送成功!发送人："+from);

		}catch(MessagingException mex){
			mex.printStackTrace();
			result[0]="1";
			result[1]="邮件服务器发生错误";

			if(mex instanceof AuthenticationFailedException){
				result[1]="用户名或密码错误";
			}
		} catch (Exception e) {
			e.printStackTrace();
			result[0]="1";
			result[1]="系统异常";
		}


		return result;
	}

    /**
     * 发送邮件
     * @return 发送状态信息 index0：状态 0成功 1失败;index1：描述错误信息
     */
    public String[] sendAttachMail(){
        String[] result=new String[2];

        Session session=null;
        Properties props = System.getProperties();

        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        props.setProperty("mail.smtp.host", host);
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.user", username);
        props.setProperty("mail.smtp.pass", password);

        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        //邮箱发送服务器端口,这里设置为465端口
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");

//		props.put("mail.smtp.host", props);
//		props.put("mail.smtp.sendpartial", "true");
//		props.put("mail.smtp.port", port);

        if(StringUtils.isBlank(username)){//不需要验证用户名密码
            session = Session.getDefaultInstance(props, null);
        }else{
            props.put("mail.smtp.auth", "true");
            EmailAuthenticator auth = new EmailAuthenticator(username, password);
            session = Session.getInstance(props, auth);
        }

        //设置邮件发送信息
        try{
            // 创建邮件
            MimeMessage message = new MimeMessage(session);
            // 自定义昵称
            String nick = SystemConfig.p.getProperty("nickname");
            if(com.cftech.core.util.StringUtils.isNotBlank(nick)){
                nick=javax.mail.internet.MimeUtility.encodeText(nick);
                message.setFrom(new InternetAddress(nick+" <"+from+">"));
            }else{
                message.setFrom(new InternetAddress(from));
            }

            // 设置收件人地址（多个邮件地址）
            InternetAddress[] toAddr = InternetAddress.parse(to);
            message.addRecipients(Message.RecipientType.TO, toAddr);
            //抄送人
            if(StringUtils.isNotBlank(cc)){
                InternetAddress[] toAddrCC = InternetAddress.parse(cc);
                message.addRecipients(Message.RecipientType.CC, toAddrCC);
            }

            // 设置邮件主题
            message.setSubject(title);

            // 设置发送时间
            message.setSentDate(new Date());
            // 设置发送内容
            Multipart multipart = new MimeMultipart();
            MimeBodyPart contentPart = new MimeBodyPart();
//			contentPart.setText(content);

            contentPart.setContent(content,"text/html;charset=gb2312");

            multipart.addBodyPart(contentPart);
            //设置附件
            if(attachmentlist!=null && attachmentlist.size()>0){
                for(int i = 0 ; i < attachmentlist.size();i++){
                    MimeBodyPart attachmentPart = new MimeBodyPart();

                    FileDataSource source = new FileDataSource(attachmentlist.get(i));
                    attachmentPart.setDataHandler(new DataHandler(source));
                    attachmentPart.setFileName(MimeUtility.encodeWord(fileNames.get(i), "gb2312", null));
                    multipart.addBodyPart(attachmentPart);
                }
            }
//			message.setContent(content,"text/html;charset=gb2312");
            message.setContent(multipart);
            //登录SMTP服务器
            if (StringUtils.isBlank(username)) {
                // 不需验证
                Transport.send(message);
            } else {
                // 需要验证
                Transport transport = session.getTransport("smtp");
                transport.connect();
                transport.sendMessage(message, message.getAllRecipients());
                transport.close();
            }

            result[0]="0";
            result[1]="发送成功";

            logger.info("邮件发送成功!发送人："+from);

        }catch(MessagingException mex){
            mex.printStackTrace();
            result[0]="1";
            result[1]="邮件服务器发生错误";

            if(mex instanceof AuthenticationFailedException){
                result[1]="用户名或密码错误";
            }
        } catch (Exception e) {
            e.printStackTrace();
            result[0]="1";
            result[1]="系统异常";
        }


        return result;
    }

	/**
	 * 发送带福建 邮件
	 * @param host
	 * @param from
	 * @param to
	 * @param title
	 * @param content
	 * @param files
	 * @param userName
	 * @param passWord
	 * @param port
	 * @return 发送状态信息 index0：状态 0成功 1失败;index1：描述错误信息
	 */
	public static String [] sendAttachEmail(String host,String from, String to,String title,String content,List<File> files,String userName,String passWord,String port,String fileName)
	{
		EmailSenderWithAttach sender=new EmailSenderWithAttach(host,from,to,title,content,
				files,userName,passWord,port, fileName);
		return sender.sendMail();
	}

	/**
	 * 发送带福建 邮件
	 * @param host
	 * @param from
	 * @param to
	 * @param title
	 * @param content
	 * @param files
	 * @param userName
	 * @param passWord
	 * @param port
	 * @return 发送状态信息 index0：状态 0成功 1失败;index1：描述错误信息
	 */
	public static String [] sendAttachEmail(String host,String from, String to,String title,String content,List<File> files,String userName,String passWord,String port,String fileName,String cc)
	{
		EmailSenderWithAttach sender=new EmailSenderWithAttach(host,from,to,cc,title,content,
				files,userName,passWord,port, fileName);
		return sender.sendMail();
	}

	/**
	 * 发送带福建 邮件
	 * @param host
	 * @param from
	 * @param to
	 * @param title
	 * @param content
	 * @param files
	 * @param userName
	 * @param passWord
	 * @param port
	 * @return 发送状态信息 index0：状态 0成功 1失败;index1：描述错误信息
	 */
	public static String [] sendAttachEmail(String host,String from, String to,String title,String content,List<File> files,String userName,String passWord,String port,List<String> fileNames,String cc)
	{
		EmailSenderWithAttach sender=new EmailSenderWithAttach(host,from,to,cc,title,content,
				files,userName,passWord,port, fileNames);
		return sender.sendAttachMail();
	}
//	public static void main(String[] args){
//		List list=new ArrayList();
//		list.add(new File("c:\\baobiao.txt"));
//		EmailSenderWithAttach sender=new EmailSenderWithAttach("smtp.qq.com","408274846@qq.com","625515@qq.com","测试邮件","测试内容",
//				list,"408274846@qq.com","866722688","25");
//		String [] result = sender.sendMail();
//		System.out.println(result[1]+"ffffffffffffffff");
//	}
}

/**
 * class MyAuthenticator用于邮件服务器认证 构造器需要用户名、密码作参数
 */
class EmailAuthenticator extends Authenticator {

	private String username = null;

	private String password = null;

	public EmailAuthenticator(String username, String password) {
		this.username = username;
		this.password = password;
	}

	public PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(username, password);
	}
}
