
/*---------------------------------------------------------------------------*/
/* smtp.h                                                                    */
/* copyright (c) innovaphone 2016                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

/*#define TEXT_PLAIN      "text/plain"  //[RFC1521]
#define TEXT_HTML       "text/html"   //[RFC1866]
#define IMG_JPG         "image/jpeg"  //[RFC1521]
#define IMG_GIF         "image/gif"   //[RFC1521]
#define VIDEO_MPEG      "video/mpeg"  //[RFC1521]
#define APPLICATION_GZIP    "application/gzip"
#define APPLICATION_PDF    "application/pdf"
*/

enum smtp_oauth2_type
{
    SMTP_OAUTH2_OFF,
    SMTP_OAUTH2_EXCHANGE,
    SMTP_OAUTH2_MICROSOFT365,
    SMTP_OAUTH2_GMAIL,
    SMTP_OAUTH2_GOOGLE,
    SMTP_OAUTH2_CLIENT_SECRET_POST,
    SMTP_OAUTH2_PRIVATE_KEY_JWT
};

class ISmtpProvider* CreateSmtpProvider();

class ISmtpProvider {
public:
    virtual ~ISmtpProvider() {}
    virtual class ISmtp* CreateSmtp(class IIoMux* iomux, class ISocketProvider* tcpSocketProvider, class ISocketProvider* tlsSocketProvider, class IInstanceLog* const log, class IDns* const dns = nullptr, class IOAuth2Client* oauth2Client = nullptr) = 0;
};

class ISmtp {

public:
    enum ContentTypes {
        ContentTextHtml,
        ContentTextPlain,
        ContentUnknown
    };

    virtual ~ISmtp() {}
    virtual class ISmtpSend* CreateSend(const char* from, const char* fromName, const char* subject, const char* host, const char* server, const char* userSmtp, const char* password, const char* oauth2 = NULL) = 0;
    virtual void SendChunk(const char* attachmentChunk, int sChunk, bool lastChunk, dword fileIndex) = 0;
    virtual class ISmtpListen * CreateListen(class USmtpListen * USmtpListen, class ISocketContext * tlsSocketContext = 0, word port = 25) = 0;
};

class ISmtpSend : public ITask {
public:
    virtual void SetOAuth2(unsigned smtp_oauth2_type, const char* client_id, const char* client_secret, const char* owner_usr, const char* owner_pwd, const char* client_email, const char* private_key_id, const char* private_key, const char* tenant, const char* token_endpoint, const char* scope) = 0;
    virtual void AddAttachment(const char* attachmentUrl, const char* mimeType = nullptr) = 0;
    virtual void AddTo(const char* rcpt) = 0;
    virtual void AddCc(const char* rcpt) = 0;
    virtual void AddBcc(const char* rcpt) = 0;
    virtual void AddBody(const char* data, const char* format, const char* charset) = 0;
};

class ISmtpListen {
public:
    virtual ~ISmtpListen() {};
    virtual class ISmtpReceive * CreateReceive(const char * user, const char * password, const char * domain) = 0;
    virtual void Shutdown() = 0;
};

class USmtpListen {
public:
    virtual ~USmtpListen() {};
    virtual void SmtpListenResult(class ISmtpReceive * smtpRecv) = 0;
    virtual void SmtpListenShutdownComplete() = 0;
    virtual class ISmtpReceive * CreateSmtpReceive() = 0;
};

class USmtpReceive {
public:
    virtual ~USmtpReceive() {};
    virtual void SmtpReceiveCancelComplete() = 0;
    virtual void CallRecvBody() = 0;
    virtual void SmtpHeader() = 0;
    virtual void SmtpBody(char * buffer, int length, bool complete) = 0;
};

class ISmtpReceive {
public:
    virtual ~ISmtpReceive() {}
    virtual void Cancel() = 0;
    virtual void Receive() = 0;
    virtual void Accept(USmtpReceive * receive) = 0;
    virtual char * GetTo() = 0;
    virtual char * GetFrom() = 0;
    virtual char * GetSubject() = 0;
    virtual char * GetDate() = 0;
    virtual char * GetFileName() = 0;
    virtual enum ISmtp::ContentTypes GetContentType(const char ** type = 0) = 0;
    virtual const char * GetXForwardedFor() = 0;
    virtual void RecvBody(char * mBuffer, int len) = 0;
    virtual void RecvAttachment(char * mBuffer, int len) = 0;
};

#define SMTP_SERVER_MICROSOFT               "smtp.office365.com:587"
#define SMTP_SERVER_GOOGLE                  "smtp.gmail.com:587"
#define OAUTH2_SCOPE_SMTP_SEND_MICROSOFT    "https://outlook.office.com/.default"
#define OAUTH2_SCOPE_SMTP_SEND_GOOGLE       "https://mail.google.com/"

extern const char * SmtpOAuth2Values[];
extern const char * SmtpOAuth2Texts[];

const char * SmtpOAuth2DefaultServer(unsigned smtp_oauth2_type);
#define SMTP_OAUTH2_CREDENTIALS_MAX         8192
unsigned SmtpOAuth2CredentialsString(char *oauth2_buf, unsigned oauth2_len, unsigned smtp_oauth2_type, const char *client_id, const char *client_secret, const char *owner_usr, const char *owner_pwd, const char *client_email, const char *private_key_id, const char *private_key, const char *tenant, const char *token_endpoint, const char *scope);
