#include "__SMTP_DATA.h"
#include "SMTPServer.h"
#include "Log.h"
#include <chrono>
#include <iomanip>

#define CRLF "\r\n"

namespace mail {
      
   int __SMTP_DATA::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {

       switch(session.mode) {
	 
        case WAIT_FOR_DATA:
	  
	  switch(session.state) {
	     
	   case RCPT:
	     session.out << "354 Enter the mail message terminated by <CRLF>.<CRLF>" << CRLF;	 
	     session.mailData.str("");
	     session.mode = RECEIVE_DATA;
	     grabInput(session);		  
	     //	       setTimer(120.0f);
	     break;
	     
	   case MAIL:
	     session.out << "503 Please use RCPT first" << CRLF;	 
	     break;
	     
	   default:
	     session.out << "503 Please use MAIL first" << CRLF;	 	    
	     break;
	     
	  }
	  break;
	  
	case RECEIVE_DATA:
	  if(request.str() != ".") 
	    session.mailData << request.str() << CRLF;	     	    	    
	  else {		 
	     session.mode = WAIT_FOR_DATA;  	       
	     session.state = READY;
	     clearGrab(session);
	     //	       if(filterMessage(session.mailData)) {	    		    
	     if(session.recipientList.size() > 0) {		      
		if(session.mailData.str().size() > 0) { 
		   std::string ID = queueMail(server, session.sender, session.recipientList, session.mailData);
		   if(ID != "") {     
		      coreutils::Log(coreutils::LOG_INFO) << "Queued message " << ID << ".";
		      session.out << "250 OK Queued message " << ID << CRLF;		  
		   }
		   else		     
		     session.out << "550 Mail message too big" << CRLF; 
		} else 
		  session.out << "550 Mail message was empty" << CRLF;		   
	     } else 	       
	       session.out << "250 OK Queued message " << CRLF; 
	     //	       } else 	    
	     //		 data << "550 Message is probably spam" << CRLF;
	  }
	  break;	 
       }
      return 1;
   }
   
   std::string __SMTP_DATA::generateMailFileName() {
      std::stringstream temp;
      struct timespec timex;
      clock_gettime(CLOCK_REALTIME, &timex);
      temp << timex.tv_sec << "." << std::setfill('0') << std::setw(9) << timex.tv_nsec; 
      return temp.str();	
   }      
   
   std::string __SMTP_DATA::queueMail(SMTPServer &server, std::string sender, std::vector<std::string> recipientList, std::stringstream &mailData) { 
      std::string fileName = server.mailFileSystem.getMailPath() + "/.queue/" + generateMailFileName();
      coreutils::File mailFile(fileName, O_CREAT | O_WRONLY, 0660);
      mailFile.write(mailData.str());      
      
      for(std::string recipient: recipientList) {
	 std::string newName = fileName + recipient;
	 link(fileName.c_str(), newName.c_str());
      }
      
      unlink(fileName.c_str());
      
      return fileName;
   }
   
}

