#pragma once

#include <fieldstat/fieldstat_easy.h>
enum http_decoder_stat_type
{
    HTTP_C2S_BYTES = 0,
    HTTP_S2C_BYTES,
    HTTP_C2S_TCP_SEG,
    HTTP_S2C_TCP_SEG,
    HTTP_C2S_HEADERS,
    HTTP_S2C_HEADERS,
    HTTP_C2S_ZIP_BYTES,   // only if Content-Encoding is gzip, deflate, br
    HTTP_S2C_ZIP_BYTES,   // only if Content-Encoding is gzip, deflate, br
    HTTP_C2S_UNZIP_BYTES, // only if Content-Encoding is gzip, deflate, br
    HTTP_S2C_UNZIP_BYTES, // only if Content-Encoding is gzip, deflate, br
    HTTP_URL_BYTES,
    HTTP_SESSION_NEW,
    HTTP_SESSION_FREE,
    HTTP_TRANSACTION_NEW,
    HTTP_TRANSACTION_FREE,
    HTTP_C2S_ASYMMETRY_SESSION,
    HTTP_S2C_ASYMMETRY_SESSION,
    HTTP_C2S_ASYMMETRY_TRANSACTION,
    HTTP_S2C_ASYMMETRY_TRANSACTION,
    HTTP_STAT_PARSE_ERR,
    HTTP_STAT_MAX,
};

struct hd_stat_config_tuple
{
    enum http_decoder_stat_type type;
    const char *name;
};

struct hd_statistics
{
    long long time_ms[HTTP_STAT_MAX];
    long long counter[HTTP_STAT_MAX];
    int batch[HTTP_STAT_MAX]; // call fieldstat_easy_counter_incrby() per batch
} __attribute__((aligned(64)));

struct http_decoder_stat
{
    pthread_t timer_pid;
    long long current_time_ms;
    struct fieldstat_easy *fse;
    int stat_interval_pkts; // call fieldstat_incrby every stat_interval_pkts
    int stat_interval_time; // second
    int field_stat_id[HTTP_STAT_MAX];
    struct hd_statistics *stats; // size is thread number
};

int http_decoder_stat_init(struct http_decoder_stat *hd_stat, int thread_max, int stat_interval_pkts, int stat_interval_time);
void http_decoder_stat_free(struct http_decoder_stat *hd_stat);
void http_decoder_stat_update(struct http_decoder_stat *hd_stat, int thread_id, enum http_decoder_stat_type type, long long value);
