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

typedef enum {
    RPT_HTTP,
    RPT_PASSTHROUGH,
    RPT_WEBSOCKET
} registered_path_type_t;

class WSRegisteredPath : public istd::listElement<WSRegisteredPath> {
private:
    UWebserverPlugin * const user;
    byte * rawBuffer;
    size_t rawBufferSize;
    char * path;
    char * staticFilePrefix;
    size_t staticFilePfxLen;
    bool mapStaticFiles;
    wsp_path_type_t pathType;

public:
    WSRegisteredPath(UWebserverPlugin * user,
                     const char * path,
                     const char * staticFilePfx,
                     const char * authUser,
                     const char * authPwd,
                     bool dynAuth,
                     bool mapStaticFiles,
                     wsp_path_type_t pathType,
                     IInstanceLog * const log)
        : user(user)
    {
        this->pathType = pathType;
        this->staticFilePrefix = nullptr;
        this->staticFilePfxLen = 0;

        if (staticFilePfx != nullptr) {
            while (*staticFilePfx != '\0' && (*staticFilePfx == '/' || *staticFilePfx == ' '))
                ++staticFilePfx;

            size_t len = strlen(staticFilePfx);
            const char * end = staticFilePfx + len - 1;
            while (end != staticFilePfx && (*end == '/' || *end == ' '))
                --end;
            if (end != staticFilePfx || *end != ' ') {
                this->staticFilePfxLen = end - staticFilePfx + 2; // + 2 for the '/' to add at the end and one for the 1 byte substracted for the end ptr above.
                char * tmp = static_cast<char *>(malloc(this->staticFilePfxLen + 1));
                this->staticFilePrefix = tmp;
                memcpy(tmp, staticFilePfx, this->staticFilePfxLen);
                tmp += staticFilePfxLen - 1;
                *tmp++ = '/';
                *tmp = '\0';
            }
        }
        
        // The protocol version isn't needed here.
        ExtendedHeader extHeader(log, 0);
        extHeader.SetPathToRegister(path);
        extHeader.SetAuthInfos(authUser, authPwd);
        extHeader.SetDynamicAuthentication(dynAuth);
        this->rawBufferSize = extHeader.BufferSize();
        this->rawBuffer = static_cast<byte *>(malloc(this->rawBufferSize));
        extHeader.Encode(0, this->rawBuffer);

        this->rawBuffer = const_cast<byte *>(extHeader.Buffer());
        this->rawBufferSize = extHeader.BufferSize();
        
        // A little bit stupid - but the buffer must be decoded again, to know where
        // the path lies inside that buffer...
        extHeader.Decode(0, this->rawBuffer, this->rawBufferSize);
        this->path = extHeader.PathToRegister();

        this->mapStaticFiles = mapStaticFiles;
    }

    ~WSRegisteredPath()
    {
        // this->path don't need to be freed because it only points to rawBuffer...
        free(this->rawBuffer);
        free(this->staticFilePrefix);
    }

    UWebserverPlugin * GetUser() { return this->user; }
    byte * GetRawBuffer() { return this->rawBuffer; }
    size_t GetRawBufferSize() { return this->rawBufferSize; }
    const char * GetPath() { return this->path; }
    bool HadStaticFilesMapped() { return this->mapStaticFiles; }
    wsp_path_type_t PathType() { return this->pathType; }
    size_t StaticFilePfxLen() { return this->staticFilePfxLen; }
    const char * StaticFilePrefix() { return this->staticFilePrefix; }
};
