
import smtpTransport = require('nodemailer-smtp-transport');
import nodemailer = require('nodemailer');
import fs = require('fs');
import util = require('./util');
import * as ramdonString from './randomString'
import * as async from 'async'

const proxyViaEmailTest = 'test@Vpn.Email';

export const getImapHost = ( email: string ) => {
	
	const yahoo = ( domain: string ) => {
		
		if ( /yahoo.co.jp$/.test(domain))
			return 'yahoo.co.jp';
			
		if ( /((.*\.){0,1}yahoo|yahoogroups|yahooxtra|yahoogruppi|yahoogrupper)(\..{2,3}){1,2}$/.test ( domain ))
			return 'yahoo.com';
		
		if ( /(^hotmail|^outlook|^live|^msn)(\..{2,3}){1,2}$/.test ( domain ))
			return 'hotmail.com';
			
		if ( /^(me|^icould|^mac)\.com/.test ( domain ))
			return 'me.com'

		return domain
	}
	const emailSplit = email.split ('@');
	
	if ( emailSplit.length !== 2 ) 
		return null
		
	const domain = yahoo ( emailSplit [ 1 ])
	
	const ret = {
		imap: 'imap.' + domain,
		smtp: 'smtp.' + domain,
		SmtpPort: [ 587, 465 ],
		ImapPort: 993,
		imapSsl: true,
		smtpSsl: true,
		haveAppPassword: false,
		ApplicationPasswordInformationUrl:[
		]
	}
	
	switch ( domain ) {
		//		yahoo domain have two different 
		//		the yahoo.co.jp is different other yahoo.*
		case 'yahoo.co.jp': {
			ret.imap = 'imap.mail.yahoo.co.jp';
			ret.smtp = 'apple.smtp.mail.yahoo.co.jp'
			
		}
		break;

		//			gmail
		case 'google.com':
		case 'googlemail.com':
		case 'gmail': {
			ret.haveAppPassword = true;
			ret.ApplicationPasswordInformationUrl = [
				'https://support.google.com/accounts/answer/185833?hl=zh-Hans',
				'https://support.google.com/accounts/answer/185833?hl=ja',
				'https://support.google.com/accounts/answer/185833?hl=en'
			]
		}
		break;
		
		//				yahoo.com
		case 'rocketmail.com':
		case 'y7mail.com':
		case 'ymail.com':
		case 'yahoo.com': {
			ret.imap = 'imap.mail.yahoo.com'
			ret.smtp = (/^bizmail.yahoo.com$/.test(emailSplit[1]))
				? 'smtp.bizmail.yahoo.com'
				: 'smtp.mail.yahoo.com'
			ret.haveAppPassword = true;
			ret.ApplicationPasswordInformationUrl = [
				'https://help.yahoo.com/kb/SLN15241.html',
				'https://help.yahoo.com/kb/SLN15241.html',
				'https://help.yahoo.com/kb/SLN15241.html'
			]
		}
		break;
		
		//		gmx.com
		
		case 'gmx.com' : {
			ret.smtp = 'mail.gmx.com'
		}
		break;
		
		//		aim.com
		case 'aim.com': {
			ret.imap = 'imap.aol.com'
		}
		break;
		
		//	outlook.com
		case 'windowslive.com':
		case 'hotmail.com': 
		case 'outlook.com': {
			ret.imap = 'imap-mail.outlook.com'
			ret.smtp = 'smtp-mail.outlook.com'
		}
		break;
		
		//			apple mail
		case 'me.com': {
			ret.imap = 'imap.mail.me.com'
			ret.smtp = 'smtp.mail.me.com'
			
		}
		break;
		
		//			163.com
		case '126.com':
		case '163.com': {
			ret.imap = 'appleimap.' + domain
			ret.smtp = 'applesmtp.' + domain
			ret.SmtpPort = [465]
		}
		break;
		
		case 'sina.com':
		case 'yeah.net': {
			ret.SmtpPort = [465]
			ret.smtpSsl = false
		}
		break;
		
	}
	
	return ret
	
}
export const sendEmail = 
	( option: smtpTransport.SmtpOptions, to: string, text: string, fromEmail: string, sbject: string, cb: ICallBack) => {

	let transporter = nodemailer.createTransport ( smtpTransport ( option ));

	let sendMailOption  = {
		from: fromEmail,
		to: [ to ],
		text: text,
		subject: sbject,
		attachments: [{
            filename: ramdonString.getRamdomFileName (4,'_') + '.bin',
            content: text
        }]
	}
	console.log ('send email to :', to)
	transporter.sendMail ( sendMailOption, cb )
	
	
}
export const testSMTP = ( host: string, user: string, password: string, port: number, tls: boolean, CallBack: ICallBack ) => {
    const option: smtpTransport.SmtpOptions = {
        host:host,
        port: port,
        requireTLS: tls,
        auth: {
            user: user,
            pass: password
        }
    }
	let transporter = nodemailer.createTransport ( smtpTransport ( option ))
    
	transporter.verify ( err => {
		if ( err ) {
			if ( /Invalid login/.test ( err.message ))
                return CallBack ( new Error ( 'passwordErrMsg' ))
			if ( /Greeting never received|Connection timeout/.test ( err.message ))
                return CallBack ( new Error ( 'hostPortTimeOut' ))
			if ( /getaddrinfo ENOTFOUND/.test ( err.message ))
                return CallBack ( new Error ( 'hostAddrErr' ))
			if ( /unable to verify the first certificate|Hostname\/IP doesn't match certificate's/.test ( err.message ))
                return CallBack ( new Error ( 'hostCertError' ))
			if (/ECONNREFUSED/.test ( err.message ))
				return CallBack ( new Error ( 'ECONNREFUSED' ))
			return CallBack ( new Error ( 'UnknowErr' ))
		}
		CallBack()
	})
}

export const tryConnectEmail = ( SockSession: ISockSession ) => {
		
	const env = SockSession.imapArray;
	env.systemPassword = null;
    const option: smtpTransport.SmtpOptions = {
        host: env.smtpServer,
        port: parseInt ( env.smtpPortNumber ),
        requireTLS: env.smtpSsl,
        auth: {
            user: env.smtpUserName,
            pass: env.smtpUserPassword
        }
    }
	const key = SockSession.keyPair;
	env.dummyData = ramdonString.getRamdomFileName ( Math.random () * 8000, ' ');
	env.publicKey = key.publicKeyUTF8;
    async.waterfall ([
        next => util.Encrypt (JSON.stringify ( env ), SockSession.vpnEmailPublicKey, key.privateKeyUTF8, SockSession.keyPairPassword, next ),
        ( data, next ) => {
            const mail: nodemailer.SendMailOptions = {
                from: env.email,
                to: [ proxyViaEmailTest ],
                subject: 'test',
                attachments: [{
                    content: data
                }]
            }
            const transporter = nodemailer.createTransport ( smtpTransport ( option ));
            transporter.sendMail ( mail, next )
        }
    ], ( err, data ) => {
        if ( err )
            return ;
		console.log ( 'SMTP sent mail success!' )
		SockSession.sentEmail = new Date().getTime()
		env.dummyData = null

    })
}
