
/*---------------------------------------------------------------------------*/
/* whatsappclient.h                                                          */
/* copyright (c) innovaphone 2024                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

typedef enum {
    WHATSAPP_ERR_OK = 0,
    WHATSAPP_ERR_MISSING_CONFIG,
    WHATSAPP_ERR_NOT_FOUND,
    WHATSAPP_ERR_BAD_REQUEST,
    WHATSAPP_ERR_AUTHENTICATION_FAILED,
    WHATSAPP_ERR_OTHER_HTTP,
    WHATSAPP_ERR_CLOSING
} whatsapp_error_t;

inline const char* WhatsAppErrorToStr(whatsapp_error_t error)
{
    const char* result = "<unkown reason id>";
    switch (error) {
    case WHATSAPP_ERR_OK: result = "WHATSAPP_ERR_OK"; break;
    case WHATSAPP_ERR_MISSING_CONFIG: result = "WHATSAPP_ERR_MISSING_CONFIG"; break;
    case WHATSAPP_ERR_NOT_FOUND: result = "WHATSAPP_ERR_NOT_FOUND"; break;
    case WHATSAPP_ERR_BAD_REQUEST: result = "WHATSAPP_ERR_BAD_REQUEST"; break;
    case WHATSAPP_ERR_AUTHENTICATION_FAILED: result = "WHATSAPP_ERR_AUTHENTICATION_FAILED"; break;
    case WHATSAPP_ERR_OTHER_HTTP: result = "WHATSAPP_ERR_OTHER_HTTP"; break;
    case WHATSAPP_ERR_CLOSING: result = "WHATSAPP_ERR_CLOSING"; break;
    }
    return result;
}

enum onboardingStatus {
    UNSTARTED,
    FETCH_TOKEN,
    REGISTER_WEBHOOKS,
    REGISTER_PHONE,
    FINISHED
};

inline const char* OnobardingStatusToStr(onboardingStatus status)
{
    const char* result = "<unkown status id>";
    switch (status) {
    case UNSTARTED: result = "UNSTARTED"; break;
    case FETCH_TOKEN: result = "FETCH_TOKEN"; break;
    case REGISTER_WEBHOOKS: result = "REGISTER_WEBHOOKS"; break;
    case REGISTER_PHONE: result = "REGISTER_PHONE"; break;
    case FINISHED: result = "FINISHED"; break;
    }
    return result;
}


class IWhatsAppClient {
public:
    static IWhatsAppClient * Create(class IIoMux * const iomux,
        class UWhatsAppClient * const user,
        class IWebserverPlugin * const webserver,
        class ISocketProvider * const tcpSocketProvider,
        class ISocketProvider * const tlsSocketProvider,
        class IInstanceLog * const log,
        class IDns * const dns = nullptr,
        class ISocketContext * const socketContext = nullptr);

    virtual ~IWhatsAppClient() {};
    virtual void Close() = 0;
    virtual void SetConfig(const char * token, const char * secret) = 0;
    virtual void SetWebhookToken(const char* webhookToken) = 0;
    virtual void SendMessage(UWhatsAppClient* context, json_io value, word base, const char* remoteNum, const char* type, const char* channel, const char* callback_info = 0, const char* refersToID = 0) = 0;
    virtual const char* GetVersion() = 0;
    virtual void RequestMedia(UWhatsAppClient * context, const char* destination, const char* mediaID, const char* detailsType) = 0;
    virtual void UploadMedia(UWhatsAppClient* context, byte* value, size_t len, const char* remoteNum, const char* type, const char* filename, const char* channel, const char* callback_info, bool firstChunk, bool lastChunk) = 0;
};

class UWhatsAppClient {
public:
    virtual ~UWhatsAppClient() {};

    virtual void WhatsAppClientCloseComplete(IWhatsAppClient * const whatsappClient) = 0;
    virtual void WhatsAppClientSendMessageResult(IWhatsAppClient * const whatsappClient, whatsapp_error_t error, const char * callback_info = 0, const char * content = 0) = 0;
    virtual void WhatsAppClientRecvMessage(IWhatsAppClient* const whatsappClient, json_io value, const char* remoteNum, const char* dn, const char* channel, const char* type, const char* id, const char* refersToID = 0) = 0;
    virtual void WhatsAppClientRecvMedia(IWhatsAppClient* const whatsappClient, const char* remoteNum, const char* dn, const char * channel, const char* wamid, const char* mediaid, const char* mimeType, char* caption = 0) = 0;
    virtual void WhatsAppClientGetNextChunk(IWhatsAppClient* const whatsappClient, const char* channel) = 0;
    //virtual void WhatsAppClientOnboardResult(IWhatsAppClient* const whatsappClient, const char* callback_info, const char* token = 0) = 0;
};

class IWhatsAppOnboarding {
public:
    static IWhatsAppOnboarding* Create(class IIoMux* const iomux,
        class UWhatsAppOnboarding* const user,
        class ISocketProvider* const tcpSocketProvider,
        class ISocketProvider* const tlsSocketProvider,
        class IInstanceLog* const log,
        class IDns* const dns,
        class ISocketContext* const socketContext = nullptr);

    virtual ~IWhatsAppOnboarding() {};
    virtual void Close() = 0;
    virtual void Onboard(UWhatsAppOnboarding* context, const char* src, const char* version, const char* code, const char* webhookToken, const char* wabaID, const char* callbackUri, const char* phoneID, const char* phonePin) = 0;
};

class UWhatsAppOnboarding {
public:
    virtual ~UWhatsAppOnboarding() {};

    virtual void WhatsAppOnboardingCloseComplete(IWhatsAppOnboarding* const onboarding) = 0;
    virtual void WhatsAppOnboardingOnboardResult(IWhatsAppOnboarding* const onboarding, const char* callback_info, onboardingStatus status, const char* token = 0) = 0;
};