#include "SendMail.h"
#include <chrono>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>

namespace mail {
   
   SendMail::SendMail(core::EPoll &ePoll, std::string from, std::string recipient, std::string mailFileName)
     : core::TCPSession2(ePoll, "Send Mail Agent"), from(from), recipient(recipient), mailFileName(mailFileName),
     mailData(mailFileName), Timer(ePoll, 0.00f), ePoll(ePoll) {
	
	coreutils::Log(coreutils::LOG_DEBUG_1) << this->recipient;
	this->recipient.split("@");
	coreutils::Log(coreutils::LOG_DEBUG_1) << this->recipient[1];
	
	u_char nsbuff[4096];
	char *domain = this->recipient[1].c_str();
	int len = res_query(domain, ns_c_any, ns_t_mx, nsbuff, sizeof(nsbuff));
	coreutils::Log(coreutils::LOG_DEBUG_1) << ">" << len;
	ns_msg msg;
	
	ns_initparse(nsbuff, len, &msg);
	len = ns_msg_count(msg, ns_s_an);
	
	char dispbuf[4096];
	ns_rr rr;
	for (int i = 0; i < 1; i++) {
	   ns_parserr(&msg, ns_s_an, i, &rr);
	   ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
	   printf ("%s\n", dispbuf);
	}
	
	coreutils::ZString  mxArray(dispbuf);
	mxArray.split("\t");
	mxArray[3].split(" ");
	coreutils::Log(coreutils::LOG_DEBUG_1) << "MX: " << mxArray[3][1];
	
	core::IPAddress mxAddress(mxArray[3][1].c_str(), 25);
	connect(mxAddress);
	
	coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail initiated...";
	
     }
   
   SendMail::SendMail(const SendMail &copy)  : core::TCPSession2(ePoll, "Send Mail Agent"), from(copy.from), recipient(copy.recipient), mailFileName(copy.mailFileName),
     mailData(mailFileName), Timer(ePoll, 0.00f), ePoll(copy.ePoll) {}
   
   SendMail::~SendMail() {
      coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail destructing...";
   }
   
   void SendMail::onTimeout() {
      state = stateOnTimeout;
      coreutils::Log(coreutils::LOG_DEBUG_1) << "onTimeout...";
      protocol(buffer);
      TCPSession2::send();
   }
   
   void SendMail::protocol(coreutils::ZString &data) {
      
      coreutils::Log(coreutils::LOG_DEBUG_1) << "[" << data << "..." << state;
      
      switch (state) {
	 
       case CONNECT:
	 // read recipient
	 // parse email for name and domain name
	 // open tcpsocket with connect
	 // wait for greeting
	 if(data.asInteger() == 220) {
	    out << "EHLO " << "mail.barant.com" << CRLF;
	    state = READY;
	 }
	 break;
	 
       case READY:
	 buffer = data;
	 setTimer(.05);
	 stateOnTimeout = READYX;
	 break;
	 
       case READYX:
	 if(buffer.asInteger() == 250) {
	    out << "MAIL FROM:<" << from << ">" << CRLF;
	    state = MAIL;
	 }
	 break;
	 
       case MAIL:
	 if(data.asInteger() == 250) {
	    out << "RCPT TO:<" << recipient << ">" << CRLF;
	    state = RCPT;
	 }
	 break;
	 
       case RCPT:
	 if(data.asInteger() == 250) {
	    out << "DATA" << CRLF;
	    state = DATA;
	 }
	 break;
	 
       case DATA:
	 if(data.asInteger() == 354) {
	    while(!mailData.eof()) {
	       mailData.readLine();
	       out << mailData.asZString() << CRLF;
	    }
	    out << "." << CRLF;
	    state = SENT;
	 }
	 break;
	 
       case SENT:
	 if(data.asInteger() == 250) {
	    out << "QUIT" << CRLF;
	 }
	 break;
	 
      }
      
   }
   
   std::vector<coreutils::MString>& SendMail::extractRecipientList() {
      return recipientList;
   }
   
}
