
/*---------------------------------------------------------------------------*/
/* webserver_message.h                                                       */
/* copyright (c) innovaphone 2015                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

// The header for a websocket message has always the same structure. However,
// Data transfered using that header will be different. Look at the implementation
// inside the webserver or webserver plugin, how the protocol will be used.
//
// off | size | Value
//  0  |   4  | Connection ID (0 for path registering process).
//  4  |   2  | message id (ws_message_id_t, word)
//  6  |   2  | General purpose bytes. The usage of them depends on the used message.
//  8  |   2  | size of additional data send after the header. The stucture of that
//              data depends on the message.
#define MSG_IDX_CONNECTION_ID       0
#define MSG_IDX_MESSAGE_ID          MSG_IDX_CONNECTION_ID + sizeof(dword)
#define MSG_IDX_GENERAL_PURPOSE     MSG_IDX_MESSAGE_ID + sizeof(word)
#define MSG_IDX_DATA_SIZE           MSG_IDX_GENERAL_PURPOSE + sizeof(dword)

#define MSG_MAX_HEADER_SIZE         12


class WebserverMessage : public IWebserverMessage {
private:
    IInstanceLog * const log;
    class ISocket * const socket;
    byte * buffer; // [MSG_MAX_HEADER_SIZE + MSG_EXT_HEADER_SIZE + 1];
    bool dontLog;

    char * resourceName;
    size_t resourceNameLen;
    bool sendResourceName;
    int state;

    void SetConnectionID(dword id);
    void SetMessageID(ws_message_t message);
    void SetGeneralPurpose(dword gp);

public:
    WebserverMessage(class ISocket * const socket, IInstanceLog * const log);
    virtual ~WebserverMessage();

    void DumpHeader();

   void Shutdown() override;
   void Send(const char * handlerName, dword connectionID, ws_message_t message, dword generalPurpos = 0, const void * dataBuf = NULL, size_t dataSize = 0) override;
   void WebsocketSend(dword connectionID, ws_msg_websocket_t message, ws_websocket_flags_t flags, const byte * data, size_t len) override;
   void SetBufferData(const byte * source) override;

    // IWebserverMessage
    void LogRecvMessage(const char * callingFncName, byte * buf, size_t size) override;
    byte * GetHeaderBuffer() override { return buffer; }
    size_t GetHeaderSize() override { return MSG_MAX_HEADER_SIZE; }

    dword GetConnectionID() override;
    ws_message_t GetMessageID() override;
    ws_msg_websocket_t GetWebsocketMessageID() override;
    ws_websocket_flags_t GetWebsocketFlags() override;
    dword GetGeneralPurpose() override;
    size_t GetDataSize() override;
};
