#include "SendMail.h"
#include <chrono>

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) {

       core::IPAddress mxAddress("127.0.0.1", 9025);

       connect(mxAddress);
       ePoll.registerSocket((TCPSession2 *)(this));

       coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail initiated...";

    }

   SendMail::~SendMail() {
      ePoll.unregisterSocket((TCPSession2 *)(this));
      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 " << from << 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;
   }

}
