/*
 * include/proto/hx.h
 * This file defines everything related to the internal HTTP messages.
 *
 * Copyright (C) 2018 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _PROTO_HTX_H
#define _PROTO_HTX_H

#include <common/buf.h>
#include <common/config.h>
#include <common/standard.h>
#include <common/http-hdr.h>
#include <types/htx.h>

extern struct htx htx_empty;

struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk);
struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t blksz);
struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk);

struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
                                      const struct ist old, const struct ist new);
struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
			     enum htx_blk_type mark);

struct htx_sl *htx_add_stline(struct htx *htx, enum htx_blk_type type, unsigned int flags,
			      const struct ist p1, const struct ist p2, const struct ist p3);
struct htx_sl *htx_replace_stline(struct htx *htx, struct htx_blk *blk, const struct ist p1,
				  const struct ist p2, const struct ist p3);

struct htx_blk *htx_replace_header(struct htx *htx, struct htx_blk *blk,
                                   const struct ist name, const struct ist value);

struct htx_blk *htx_add_header(struct htx *htx, const struct ist name, const struct ist value);
struct htx_blk *htx_add_all_headers(struct htx *htx, const struct http_hdr *hdrs);
struct htx_blk *htx_add_pseudo_header(struct htx *htx,  enum htx_phdr_type phdr, const struct ist value);
struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type);
struct htx_blk *htx_add_data(struct htx *htx, const struct ist data);
struct htx_blk *htx_add_trailer(struct htx *htx, const struct ist tlr);
struct htx_blk *htx_add_oob(struct htx *htx, const struct ist oob);
struct htx_blk *htx_add_data_before(struct htx *htx, const struct htx_blk *ref, const struct ist data);

int htx_reqline_to_str(const struct htx_sl *sl, struct buffer *chk);
int htx_stline_to_str(const struct htx_sl *sl, struct buffer *chk);
int htx_hdr_to_str(const struct ist n, const struct ist v, struct buffer *chk);
int htx_data_to_str(const struct ist data, struct buffer *chk, int chunked);
int htx_trailer_to_str(const struct ist tlr, struct buffer *chk);

/* Functions and macros to get parts of the start-line or legnth of these
 * parts
 */
#define HTX_SL_LEN(sl) ((sl)->len[0] + (sl)->len[1] + (sl)->len[2])

#define HTX_SL_P1_LEN(sl) ((sl)->len[0])
#define HTX_SL_P2_LEN(sl) ((sl)->len[1])
#define HTX_SL_P3_LEN(sl) ((sl)->len[2])
#define HTX_SL_P1_PTR(sl) ((sl)->l)
#define HTX_SL_P2_PTR(sl) (HTX_SL_P1_PTR(sl) + HTX_SL_P1_LEN(sl))
#define HTX_SL_P3_PTR(sl) (HTX_SL_P2_PTR(sl) + HTX_SL_P2_LEN(sl))

#define HTX_SL_REQ_MLEN(sl) HTX_SL_P1_LEN(sl)
#define HTX_SL_REQ_ULEN(sl) HTX_SL_P2_LEN(sl)
#define HTX_SL_REQ_VLEN(sl) HTX_SL_P3_LEN(sl)
#define HTX_SL_REQ_MPTR(sl) HTX_SL_P1_PTR(sl)
#define HTX_SL_REQ_UPTR(sl) HTX_SL_P2_PTR(sl)
#define HTX_SL_REQ_VPTR(sl) HTX_SL_P3_PTR(sl)

#define HTX_SL_RES_VLEN(sl) HTX_SL_P1_LEN(sl)
#define HTX_SL_RES_CLEN(sl) HTX_SL_P2_LEN(sl)
#define HTX_SL_RES_RLEN(sl) HTX_SL_P3_LEN(sl)
#define HTX_SL_RES_VPTR(sl) HTX_SL_P1_PTR(sl)
#define HTX_SL_RES_CPTR(sl) HTX_SL_P2_PTR(sl)
#define HTX_SL_RES_RPTR(sl) HTX_SL_P3_PTR(sl)

static inline const struct ist htx_sl_p1(const struct htx_sl *sl)
{
	return ist2(HTX_SL_P1_PTR(sl), HTX_SL_P1_LEN(sl));
}

static inline const struct ist htx_sl_p2(const struct htx_sl *sl)
{
	return ist2(HTX_SL_P2_PTR(sl), HTX_SL_P2_LEN(sl));
}

static inline const struct ist htx_sl_p3(const struct htx_sl *sl)
{
	return ist2(HTX_SL_P3_PTR(sl), HTX_SL_P3_LEN(sl));
}


static inline const struct ist htx_sl_req_meth(const struct htx_sl *sl)
{
	return htx_sl_p1(sl);
}

static inline const struct ist htx_sl_req_uri(const struct htx_sl *sl)
{
	return htx_sl_p2(sl);
}

static inline const struct ist htx_sl_req_vsn(const struct htx_sl *sl)
{
	return htx_sl_p3(sl);
}


static inline const struct ist htx_sl_res_vsn(const struct htx_sl *sl)
{
	return htx_sl_p1(sl);
}

static inline const struct ist htx_sl_res_code(const struct htx_sl *sl)
{
	return htx_sl_p2(sl);
}

static inline const struct ist htx_sl_res_reason(const struct htx_sl *sl)
{
	return htx_sl_p3(sl);
}

/* Returns the HTX start-line if set, otherwise it returns NULL. */
static inline struct htx_sl *htx_get_stline(struct htx *htx)
{
	struct htx_sl *sl = NULL;

	if (htx->sl_off != -1)
		sl = ((void *)htx->blocks + htx->sl_off);

	return sl;
}

/* Returns the array index of a block given its position <pos> */
static inline uint32_t htx_pos_to_idx(const struct htx *htx, uint32_t pos)
{
        return ((htx->size / sizeof(htx->blocks[0])) - pos - 1);
}

/* Returns the position of the block <blk> */
static inline uint32_t htx_get_blk_pos(const struct htx *htx, const struct htx_blk *blk)
{
        return (htx->blocks + (htx->size / sizeof(htx->blocks[0])) - blk - 1);
}

/* Returns the block at the position <pos> */
static inline struct htx_blk *htx_get_blk(const struct htx *htx, uint32_t pos)
{
        return ((struct htx_blk *)(htx->blocks) + htx_pos_to_idx(htx, pos));
}

/* Returns the type of the block <blk> */
static inline enum htx_blk_type htx_get_blk_type(const struct htx_blk *blk)
{
        return (blk->info >> 28);
}

/* Returns the pseudo-header type of the block <blk>. If it's not a
 * pseudo-header, HTX_PHDR_UNKNOWN is returned.
 */
static inline enum htx_phdr_type htx_get_blk_phdr(const struct htx_blk *blk)
{
        enum htx_blk_type type = htx_get_blk_type(blk);
        enum htx_phdr_type phdr;

        switch (type) {
                case HTX_BLK_PHDR:
                        phdr = (blk->info & 0xff);
                        return phdr;

                default:
                        /* Not a pseudo-header */
                        return HTX_PHDR_UNKNOWN;
        }
}

/* Returns the size of the block <blk>, depending of its type */
static inline uint32_t htx_get_blksz(const struct htx_blk *blk)
{
        enum htx_blk_type type = htx_get_blk_type(blk);

        switch (type) {
                case HTX_BLK_HDR:
                        /*       name.length       +        value.length        */
                        return ((blk->info & 0xff) + ((blk->info >> 8) & 0xfffff));
                case HTX_BLK_PHDR:
                        /*          value.length          */
                        return ((blk->info >> 8) & 0xfffff);
                default:
                        /*         value.length      */
                        return (blk->info & 0xfffffff);
        }
}

/* Returns the position of the oldest entry (head).
 *
 * An signed 32-bits integer is returned to handle -1 case. Blocks position are
 * store on unsigned 32-bits integer, but it is impossible to have so much
 * blocks to overflow a 32-bits signed integer !
 */
static inline int32_t htx_get_head(const struct htx *htx)
{
        if (!htx->used)
                return -1;

        return (((htx->tail + 1U < htx->used) ? htx->wrap : 0) + htx->tail + 1U - htx->used);
}

/* Returns the oldest HTX block (head) if the HTX message is not
 * empty. Otherwise it returns NULL.
*/
static inline struct htx_blk *htx_get_head_blk(const struct htx *htx)
{
	int32_t head = htx_get_head(htx);

	return ((head == -1) ? NULL : htx_get_blk(htx, head));
}

/* Returns the type of the oldest HTX block (head) if the HTX message is not
 * empty. Otherwise it returns HTX_BLK_UNUSED.
 */
static inline enum htx_blk_type htx_get_head_type(const struct htx *htx)
{
	struct htx_blk *blk = htx_get_head_blk(htx);

	return (blk ? htx_get_blk_type(blk) : HTX_BLK_UNUSED);
}

/* Returns the position of the newest entry (tail).
 *
 * An signed 32-bits integer is returned to handle -1 case. Blocks position are
 * store on unsigned 32-bits integer, but it is impossible to have so much
 * blocks to overflow a 32-bits signed integer !
 */
static inline int32_t htx_get_tail(const struct htx *htx)
{
        return (htx->used ? htx->tail : -1);
}

/* Returns the newest HTX block (tail) if the HTX message is not
 * empty. Otherwise it returns NULL.
*/
static inline struct htx_blk *htx_get_tail_blk(const struct htx *htx)
{
	int32_t tail = htx_get_tail(htx);

	return ((tail == -1) ? NULL : htx_get_blk(htx, tail));
}

/* Returns the type of the newest HTX block (tail) if the HTX message is not
 * empty. Otherwise it returns HTX_BLK_UNUSED.
 */
static inline enum htx_blk_type htx_get_tail_type(const struct htx *htx)
{
	struct htx_blk *blk = htx_get_tail_blk(htx);

	return (blk ? htx_get_blk_type(blk) : HTX_BLK_UNUSED);
}

/* Returns the position of block immediately before the one pointed by <pos>. If
 * the message is empty or if <pos> is the position of the head, -1 returned.
 *
 * An signed 32-bits integer is returned to handle -1 case. Blocks position are
 * store on unsigned 32-bits integer, but it is impossible to have so much
 * blocks to overflow a 32-bits signed integer !
 */
static inline int32_t htx_get_prev(const struct htx *htx, uint32_t pos)
{
        int32_t head;

        head = htx_get_head(htx);
        if (head == -1 || pos == head)
                return -1;
        if (!pos)
                return (htx->wrap - 1);
        return (pos - 1);
}

/* Returns the HTX block before <blk> in the HTX message <htx>. If <blk> is the
 * head, NULL returned.
*/
static inline struct htx_blk *htx_get_prev_blk(const struct htx *htx,
					       const struct htx_blk *blk)
{
	int32_t pos;

	pos = htx_get_prev(htx, htx_get_blk_pos(htx, blk));
	return ((pos == -1) ? NULL : htx_get_blk(htx, pos));
}

/* Returns the position of block immediately after the one pointed by <pos>. If
 * the message is empty or if <pos> is the position of the tail, -1 returned.
 *
 * An signed 32-bits integer is returned to handle -1 case. Blocks position are
 * store on unsigned 32-bits integer, but it is impossible to have so much
 * blocks to overflow a 32-bits signed integer !
 */
static inline int32_t htx_get_next(const struct htx *htx, uint32_t pos)
{
        if (!htx->used)
                return -1;

        if (pos == htx->tail)
                return -1;
        pos++;
        if (pos >= htx->wrap)
                pos = 0;
        return pos;

}

/* Returns the HTX block after <blk> in the HTX message <htx>. If <blk> is the
 * tail, NULL returned.
*/
static inline struct htx_blk *htx_get_next_blk(const struct htx *htx,
					       const struct htx_blk *blk)
{
	int32_t pos;

	pos = htx_get_next(htx, htx_get_blk_pos(htx, blk));
	return ((pos == -1) ? NULL : htx_get_blk(htx, pos));
}

static inline int32_t htx_find_front(const struct htx *htx)
{
        int32_t  front, pos;
        uint32_t addr = 0;

        if (!htx->used)
                return -1;

        front = -1;
        for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
                struct htx_blk   *blk  = htx_get_blk(htx, pos);
                enum htx_blk_type type = htx_get_blk_type(blk);

                if (type != HTX_BLK_UNUSED && blk->addr >= addr) {
                        front = pos;
                        addr  = blk->addr;
                }
        }

        return front;
}

/* Returns the HTX block containing data with the <offset>, relatively to the
 * beginning of the HTX message <htx>. It returns an htx_ret. if the HTX block is
 * not found, htx_ret.blk is set to NULL. Otherwise, it points to the right HTX
 * block and htx_ret.ret is set to the remaining offset inside the block.
 */
static inline struct htx_ret htx_find_blk(const struct htx *htx, uint32_t offset)
{
	int32_t pos;

	for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
		struct htx_blk *blk = htx_get_blk(htx, pos);
		uint32_t sz = htx_get_blksz(blk);

		if (offset < sz)
			return (struct htx_ret){ .blk = blk, .ret = offset };
		offset -= sz;
	}

	return (struct htx_ret){ .blk = NULL };
}
/* Changes the size of the value. It is the caller responsibility to change the
 * value itself, make sure there is enough space and update allocated value.
 */
static inline void htx_set_blk_value_len(struct htx_blk *blk, uint32_t vlen)
{
        enum htx_blk_type type = htx_get_blk_type(blk);

        switch (type) {
                case HTX_BLK_HDR:
                case HTX_BLK_PHDR:
                        blk->info = (type << 28) + (vlen << 8) + (blk->info & 0xff);
                        break;
                case HTX_BLK_REQ_SL:
                case HTX_BLK_RES_SL:
                case HTX_BLK_DATA:
                case HTX_BLK_TLR:
                case HTX_BLK_OOB:
                        blk->info = (type << 28) + vlen;
                        break;
                default:
                        /* Unexpected case */
                        break;
        }
}

/* Returns the data pointer of the block <blk> */
static inline void *htx_get_blk_ptr(const struct htx *htx, const struct htx_blk *blk)
{
	return ((void *)htx->blocks + blk->addr);
}

/* Returns the name of the block <blk>, only if it is a header. Otherwise it
 * returns an empty name.
 */
static inline struct ist htx_get_blk_name(const struct htx *htx, const struct htx_blk *blk)
{
        enum htx_blk_type type = htx_get_blk_type(blk);
        struct ist ret;

        switch (type) {
                case HTX_BLK_HDR:
                        ret.ptr = htx_get_blk_ptr(htx, blk);
                        ret.len = blk->info & 0xff;
                        break;

                default:
                        return ist("");
        }
        return ret;
}


/* Returns the value of the block <blk>, depending on its type. If there is no
 * value, an empty one is retruned.
 */
static inline struct ist htx_get_blk_value(const struct htx *htx, const struct htx_blk *blk)
{
        enum htx_blk_type type = htx_get_blk_type(blk);
        struct ist ret;

        switch (type) {
                case HTX_BLK_HDR:
                        ret.ptr = htx_get_blk_ptr(htx, blk) + (blk->info & 0xff);
                        ret.len = (blk->info >> 8) & 0xfffff;
                        break;

                case HTX_BLK_PHDR:
                        ret.ptr = htx_get_blk_ptr(htx, blk);
                        ret.len = (blk->info >> 8) & 0xfffff;
                        break;

                case HTX_BLK_REQ_SL:
                case HTX_BLK_RES_SL:
                case HTX_BLK_DATA:
                case HTX_BLK_TLR:
                case HTX_BLK_OOB:
                        ret.ptr = htx_get_blk_ptr(htx, blk);
                        ret.len = blk->info & 0xfffffff;
                        break;

                default:
                        return ist("");
        }
        return ret;
}

/* Removes <n> bytes from the beginning of DATA block <blk>. The block's start
 * address and its length are adjusted, and the htx's total data count is
 * updated. This is used to mark that part of some data were transfered
 * from a DATA block without removing this DATA block. No sanity check is
 * performed, the caller is reponsible for doing this exclusively on DATA
 * blocks, and never removing more than the block's size.
 */
static inline void htx_cut_data_blk(struct htx *htx, struct htx_blk *blk, uint32_t n)
{
	blk->addr += n;
	blk->info -= n;
	htx->data -= n;
}

/* Returns the space used by metadata in <htx>. */
static inline uint32_t htx_meta_space(const struct htx *htx)
{
        return (htx->used * sizeof(htx->blocks[0]));
}

/* Returns the space used (data + metadata) in <htx> */
static inline uint32_t htx_used_space(const struct htx *htx)
{
        return (htx->data + htx_meta_space(htx));
}

/* Returns the free space in <htx> */
static inline uint32_t htx_free_space(const struct htx *htx)
{
        return (htx->size - htx_used_space(htx));
}

/* Returns the maximum size available to store some data in <htx> if a new block
 * is reserved.
 */
static inline uint32_t htx_free_data_space(const struct htx *htx)
{
        uint32_t free = htx_free_space(htx);

        if (free < sizeof(htx->blocks[0]))
                return 0;
        return (free - sizeof(htx->blocks[0]));
}

/* Returns 1 if the message has less than 1/4 of its capacity free, otherwise 0 */
static inline int htx_almost_full(const struct htx *htx)
{
        if (!htx->size || htx_free_space(htx) < htx->size / 4)
                return 1;
        return 0;
}

static inline void htx_reset(struct htx *htx)
{
        htx->data = htx->used = htx->tail = htx->wrap  = htx->front = 0;
	htx->extra = 0;
	htx->flags = HTX_FL_NONE;
	htx->sl_off = -1;
}

/* Returns an HTX message using the buffer <buf>. */
static inline struct htx *htx_from_buf(struct buffer *buf)
{
        struct htx *htx;

        if (b_is_null(buf))
                return &htx_empty;
        htx = (struct htx *)(buf->area);
        htx->size = buf->size - sizeof(*htx);
        if (!b_data(buf))
                htx_reset(htx);
	return htx;
}

/* Returns 1 if the message is empty, otherwise it returns 0. */
static inline int htx_is_empty(const struct htx *htx)
{
        return (!htx || !htx->used);
}

/* Returns 1 if the message is not empty, otherwise it returns 0. */
static inline int htx_is_not_empty(const struct htx *htx)
{
        return (htx && htx->used);
}

/* For debugging purpose */
static inline const char *htx_blk_type_str(enum htx_blk_type type)
{
        switch (type) {
                case HTX_BLK_REQ_SL: return "HTX_BLK_REQ_SL";
                case HTX_BLK_RES_SL: return "HTX_BLK_RES_SL";
                case HTX_BLK_HDR:    return "HTX_BLK_HDR";
                case HTX_BLK_PHDR:   return "HTX_BLK_PHDR";
                case HTX_BLK_EOH:    return "HTX_BLK_EOH";
                case HTX_BLK_DATA:   return "HTX_BLK_DATA";
                case HTX_BLK_EOD:    return "HTX_BLK_EOD";
                case HTX_BLK_TLR:    return "HTX_BLK_TLR";
                case HTX_BLK_EOM:    return "HTX_BLK_EOM";
                case HTX_BLK_OOB:    return "HTX_BLK_OOB";
                case HTX_BLK_UNUSED: return "HTX_BLK_UNUSED";
                default:             return "HTX_BLK_???";
        };
}

static inline const char *htx_blk_phdr_str(enum htx_phdr_type phdr)
{
        switch (phdr) {
                case HTX_PHDR_UNKNOWN: return "HTX_PHDR_UNKNOWN";
                default:               return "HTX_PHDR_???";
        }
}

static inline void htx_dump(struct htx *htx)
{
        int32_t pos;

        fprintf(stderr, "htx:%p [ size=%u - data=%u - used=%u - wrap=%s - extra=%llu]\n",
                htx, htx->size, htx->data, htx->used,
                (!htx->used || htx->tail+1 == htx->wrap) ? "NO" : "YES",
		(unsigned long long)htx->extra);
        fprintf(stderr, "\thead=%d - tail=%u - front=%u - wrap=%u\n",
                htx_get_head(htx), htx->tail, htx->front, htx->wrap);

        for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
		struct htx_sl     *sl;
                struct htx_blk    *blk  = htx_get_blk(htx, pos);
                enum htx_blk_type  type = htx_get_blk_type(blk);
                enum htx_phdr_type phdr = htx_get_blk_phdr(blk);
                uint32_t           sz   = htx_get_blksz(blk);
                struct ist         n, v;

                n = htx_get_blk_name(htx, blk);
                v = htx_get_blk_value(htx, blk);

                if (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL) {
			sl = htx_get_blk_ptr(htx, blk);
                        fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s %.*s %.*s\n",
                                pos, htx_blk_type_str(type), sz, blk->addr,
                                HTX_SL_P1_LEN(sl), HTX_SL_P1_PTR(sl),
                                HTX_SL_P2_LEN(sl), HTX_SL_P2_PTR(sl),
                                HTX_SL_P3_LEN(sl), HTX_SL_P3_PTR(sl));
		}
                else if (type == HTX_BLK_HDR)
                        fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s: %.*s\n",
                                pos, htx_blk_type_str(type), sz, blk->addr,
                                (int)n.len, n.ptr,
                                (int)v.len, v.ptr);

                else if (type == HTX_BLK_PHDR)
                        fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s\n",
                                pos, htx_blk_phdr_str(phdr), sz, blk->addr,
                                (int)v.len, v.ptr);
                else
                        fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u%s\n",
                                pos, htx_blk_type_str(type), sz, blk->addr,
                                (!v.len ? "\t<empty>" : ""));
        }
        fprintf(stderr, "\n");
}

#endif /* _PROTO_HTX_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
