/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "config.h"
#include "http.h"
#include "server_private.h"

#include "qpid/dispatch/amqp.h"
#include "qpid/dispatch/atomic.h"
#include "qpid/dispatch/protocol_adaptor.h"
#include "qpid/dispatch/threading.h"
#include "qpid/dispatch/timer.h"

#include <proton/connection_driver.h>
#include <proton/object.h>

#include <ctype.h>
#include <inttypes.h>
#include <libwebsockets.h>

#if LWS_LIBRARY_VERSION_MAJOR > 3 || (LWS_LIBRARY_VERSION_MAJOR == 3 && LWS_LIBRARY_VERSION_MINOR >= 2)
#define QD_HAVE_MODERN_LIBWEBSOCKETS 1
#endif

static const char *CIPHER_LIST = "ALL:aNULL:!eNULL:@STRENGTH"; /* Default */
static const char *IGNORED = "ignore-this-log-message";

/* Log for LWS messages. For dispatch server messages use qd_http_server_t::log */
static qd_log_source_t* http_log;

static qd_log_level_t qd_level(int lll) {
    switch (lll) {
    case LLL_ERR: return QD_LOG_ERROR;
    case LLL_WARN: return QD_LOG_WARNING;
    /* LWS is noisy compared to dispatch on the informative levels, downgrade */
    case LLL_NOTICE: return QD_LOG_DEBUG;
    default: return QD_LOG_TRACE; /* Everything else to trace  */
    }
}

static void logger(int lll, const char *line)  {
    if (strstr(line, IGNORED)) return;
    size_t  len = strlen(line);
    while (len > 1 && isspace(line[len-1])) { /* Strip trailing newline */
        --len;
    }
    qd_log(http_log, qd_level(lll), "%.*s", (int)len, line);
}

static void log_init(void) {
    http_log = qd_log_source("HTTP");
    int levels = 0;
    for (int i = 0; i < LLL_COUNT; ++i) {
        int lll = 1<<i;
        levels |= qd_log_enabled(http_log, qd_level(lll)) ? lll : 0;
    }
    lws_set_log_level(levels, logger);
}

/* Intermediate write buffer: LWS needs extra header space on write.  */
typedef struct buffer_t {
    char *start;
    size_t size, cap;
} buffer_t;

/* Ensure size bytes in buffer, make buf empty if alloc fails */
static void buffer_set_size(buffer_t *buf, size_t size) {
    if (size > buf->cap) {
        buf->cap = (size > buf->cap * 2) ? size : buf->cap * 2;
        buf->start = realloc(buf->start, buf->cap);
    }
    if (buf->start) {
        buf->size = size;
    } else {
        buf->size = buf->cap = 0;
    }
}

/* AMQPWS connection: set as lws user data and qd_conn->context */
typedef struct connection_t {
    pn_connection_driver_t driver;
    qd_connection_t* qd_conn;
    buffer_t wbuf;   /* LWS requires allocated header space at start of buffer */
    struct lws *wsi;
} connection_t;

typedef struct stats_request_state_t {
    bool callback_completed;
    bool wsi_deleted;
    qdr_global_stats_t stats;
    qd_http_server_t *server;
    struct lws *wsi;
} stats_request_state_t;

typedef struct stats_t {
    size_t current;
    bool headers_sent;
    stats_request_state_t *context;
} stats_t;

/* Navigating from WSI pointer to qd objects */
static qd_http_server_t *wsi_server(struct lws *wsi);
static qd_lws_listener_t *wsi_listener(struct lws *wsi);
static qd_log_source_t *wsi_log(struct lws *wsi);


/* Declare LWS callbacks and protocol list */
inline static void finalize_http(struct lws_vhost *vh, void *arg);

static int callback_http(struct lws *wsi, enum lws_callback_reasons reason,
                         void *user, void *in, size_t len);
static int callback_amqpws(struct lws *wsi, enum lws_callback_reasons reason,
                           void *user, void *in, size_t len);
static int callback_metrics(struct lws *wsi, enum lws_callback_reasons reason,
                               void *user, void *in, size_t len);
static int callback_healthz(struct lws *wsi, enum lws_callback_reasons reason,
                               void *user, void *in, size_t len);

static struct lws_protocols protocols[] = {
    /* HTTP only protocol comes first */
    {
        "http-only",
        callback_http,
        0,
    },
    /* "amqp" is the official oasis AMQP over WebSocket protocol name */
    {
        "amqp",
        callback_amqpws,
        sizeof(connection_t),
    },
    /* "binary" is an alias for "amqp", for compatibility with clients designed
     * to work with a WebSocket proxy
     */
    {
        "binary",
        callback_amqpws,
        sizeof(connection_t),
    },
    {
        "http",
        callback_metrics,
        sizeof(stats_t),
    },
    {
        "healthz",
        callback_healthz,
        sizeof(stats_t),
    },
    { NULL, NULL, 0, 0 } /* terminator */
};


static inline int unexpected_close(struct lws *wsi, const char *msg) {
    lws_close_reason(wsi, LWS_CLOSE_STATUS_UNEXPECTED_CONDITION,
                     (unsigned char*)msg, strlen(msg));
    char peer[64];
    lws_get_peer_simple(wsi, peer, sizeof(peer));
    qd_log(wsi_log(wsi), QD_LOG_ERROR, "Error on HTTP connection from %s: %s", peer, msg);
    return -1;
}

static int handle_events(connection_t* c) {
    if (!c->qd_conn) {
        return unexpected_close(c->wsi, "not-established");
    }
    pn_event_t *e;
    while ((e = pn_connection_driver_next_event(&c->driver))) {
        if (c->qd_conn && e) {
            if (!qd_connection_handle(c->qd_conn, e)) {
                c->qd_conn = 0;  // connection closed
            }
        }
    }
    if (pn_connection_driver_write_buffer(&c->driver).size) {
        lws_callback_on_writable(c->wsi);
    }
    if (pn_connection_driver_write_closed(&c->driver)) {
        lws_close_reason(c->wsi, LWS_CLOSE_STATUS_NORMAL, NULL, 0);
        return -1;
    }
    return 0;
}

/* The server has a bounded, thread-safe queue for external work */
typedef struct work_t {
    enum { W_NONE, W_LISTEN, W_CLOSE, W_WAKE, W_STOP, W_HANDLE_STATS } type;
    void *value;
} work_t;

#define WORK_MAX 8              /* Just decouple threads, not a big buffer */

typedef struct work_queue_t {
    sys_mutex_t *lock;
    sys_cond_t *cond;
    work_t work[WORK_MAX];
    size_t head, len;          /* Ring buffer */
} work_queue_t;

/* HTTP Server runs in a single thread, communication from other threads via work_queue */
struct qd_http_server_t {
    qd_server_t *server;
    qdr_core_t *core;
    sys_thread_t *thread;
    work_queue_t work;
    qd_log_source_t *log;
    struct lws_context *context;
    qd_timestamp_t now;         /* Cache current time in thread_run */
    qd_timestamp_t next_tick;   /* Next requested tick service */
};

static void work_queue_destroy(work_queue_t *wq) {
    if (wq->lock) sys_mutex_free(wq->lock);
    if (wq->cond) sys_cond_free(wq->cond);
}

static void work_queue_init(work_queue_t *wq) {
    wq->lock = sys_mutex();
    wq->cond = sys_cond();
}

 /* Block till there is space */
static void work_push(qd_http_server_t *hs, work_t w) {
    work_queue_t *wq = &hs->work;
    sys_mutex_lock(wq->lock);
    while (wq->len == WORK_MAX) {
        lws_cancel_service(hs->context); /* Wake up the run thread to clear space */
        sys_cond_wait(wq->cond, wq->lock);
    }
    wq->work[(wq->head + wq->len) % WORK_MAX] = w;
    ++wq->len;
    sys_mutex_unlock(wq->lock);
    lws_cancel_service(hs->context); /* Wake up the run thread to handle my work */
}

/* Non-blocking, return { W_NONE, NULL } if empty */
static work_t work_pop(qd_http_server_t *hs) {
    work_t w = { W_NONE, NULL };
    work_queue_t *wq = &hs->work;
    sys_mutex_lock(wq->lock);
    if (wq->len > 0) {
        w = wq->work[wq->head];
        wq->head = (wq->head + 1) % WORK_MAX;
        --wq->len;
        sys_cond_signal(wq->cond);
    }
    sys_mutex_unlock(wq->lock);
    return w;
}

/* Each qd_lws_listener_t is associated with an lws_vhost */
struct qd_lws_listener_t {
    qd_listener_t *listener;
    qd_http_server_t *server;
    struct lws_vhost *vhost;
    struct lws_http_mount mount;
    struct lws_http_mount metrics;
    struct lws_http_mount healthz;
};

void qd_lws_listener_free(qd_lws_listener_t *hl) {
    if (!hl) return;
    if (hl->listener) {
        hl->listener->http = NULL;
        qd_listener_decref(hl->listener);
    }
    free(hl);
}

static qd_lws_listener_t *qd_lws_listener(qd_http_server_t *hs, qd_listener_t *li) {
    qd_lws_listener_t *hl = calloc(1, sizeof(*hl));
    if (hl) {
        hl->server = hs;
        hl->listener = li;
        li->http = hl;
        sys_atomic_inc(&li->ref_count); /* Keep it around till qd_http_server_free() */
    } else {
        qd_log(hs->log, QD_LOG_CRITICAL, "No memory for HTTP listen on %s",
               li->config.host_port);
    }
    return hl;
}

/* Linked list: first entry on each line should point to next, last line should be the 
 * octet-stream default.
 */
static const struct lws_protocol_vhost_options mime_types[] = {
    { &mime_types[1], NULL, ".json", "application/json" },
    { &mime_types[2], NULL, ".woff2", "font/woff2" },
    { NULL, NULL, "*", "application/octet-stream" }
};

static int is_ipv6_address(qd_http_server_t *hs, const char* host, const char* port)
{
    int result = 0;
    struct addrinfo *addr;
    struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM};
    int code = getaddrinfo(host, port, &hints, &addr);
    if (code) {
        qd_log(hs->log, QD_LOG_ERROR, "getaddrinfo(%s, %s) failed with %s", host, port, gai_strerror(code));
    } else {
        result = addr->ai_family == AF_INET6;
        freeaddrinfo(addr);
    }
    return result;
}

static void listener_start(qd_lws_listener_t *hl, qd_http_server_t *hs) {
    log_init();                 /* Update log flags at each listener */

    qd_server_config_t *config = &hl->listener->config;

    int port = qd_port_int(config->port);
    if (port < 0) {
        qd_log(hs->log, QD_LOG_ERROR, "HTTP listener %s has invalid port %s",
               config->host_port, config->port);
        goto error;
    }
    struct lws_http_mount *m = &hl->mount;
    m->mountpoint = "/";    /* URL mount point */
    m->mountpoint_len = strlen(m->mountpoint); /* length of the mountpoint */
    m->origin = (config->http_root_dir && *config->http_root_dir) ? /* File system root */
        config->http_root_dir : QPID_CONSOLE_STAND_ALONE_INSTALL_DIR;
    m->def = "index.html";  /* Default file name */
    m->origin_protocol = LWSMPRO_FILE; /* mount type is a directory in a filesystem */
    m->extra_mimetypes = mime_types;
    struct lws_http_mount *tail = m;
    if (config->metrics) {
        struct lws_http_mount *metrics = &hl->metrics;
        tail->mount_next = metrics;
        tail = metrics;
        metrics->mountpoint = "/metrics";
        metrics->mountpoint_len = strlen(metrics->mountpoint);
        metrics->origin_protocol = LWSMPRO_CALLBACK;
        metrics->protocol = "http";
        metrics->origin = IGNORED;
    }
    if (config->healthz) {
        struct lws_http_mount *healthz = &hl->healthz;
        tail->mount_next = healthz;
        healthz->mountpoint = "/healthz";
        healthz->mountpoint_len = strlen(healthz->mountpoint);
        healthz->origin_protocol = LWSMPRO_CALLBACK;
        healthz->protocol = "healthz";
        healthz->origin = IGNORED;
    }

    struct lws_context_creation_info info = {0};
    info.mounts = m;
    info.port = port;
    info.protocols = protocols;
    info.keepalive_timeout = 1;
    info.ssl_cipher_list = CIPHER_LIST;
    info.options |= LWS_SERVER_OPTION_VALIDATE_UTF8;
    if (!is_ipv6_address(hs, config->host, config->port)) {
        qd_log(hs->log, QD_LOG_NOTICE, "Disabling ipv6 on %s", config->host_port);
        info.options |= LWS_SERVER_OPTION_DISABLE_IPV6;
    }
    if (config->ssl_profile) {
        info.ssl_cert_filepath = config->ssl_certificate_file;
        info.ssl_private_key_filepath = config->ssl_private_key_file;
        info.ssl_private_key_password = config->ssl_password;
        info.ssl_ca_filepath = config->ssl_trusted_certificate_db;
        info.ssl_cipher_list = config->ssl_ciphers;

        info.options |=
            LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
#ifdef QD_HAVE_MODERN_LIBWEBSOCKETS
            (config->ssl_required ? 0 : LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT | LWS_SERVER_OPTION_ALLOW_HTTP_ON_HTTPS_LISTENER) |
#else
            (config->ssl_required ? 0 : LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) |
#endif
            ((config->requireAuthentication && info.ssl_ca_filepath) ? LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT : 0);
    }
    info.vhost_name = hl->listener->config.host_port;
#ifdef QD_HAVE_MODERN_LIBWEBSOCKETS
    info.finalize = finalize_http;
    info.finalize_arg = hl;
#endif
    hl->vhost = lws_create_vhost(hs->context, &info);
    if (!hl->vhost) {
        qd_log(hs->log, QD_LOG_NOTICE, "Error listening for HTTP on %s", config->host_port);
        goto error;
    }

    /* Store hl pointer in vhost */
    void *vp = lws_protocol_vh_priv_zalloc(hl->vhost, &protocols[0], sizeof(hl));
    memcpy(vp, &hl, sizeof(hl));

    if (port == 0) {
        // If a 0 (zero) is specified for a port, get the actual listening port from the listener.
        const int resolved_port = lws_get_vhost_port(hl->vhost);
        assert(resolved_port != -1); // already checked the vhost is successfully started
        if (config->name)
            qd_log(hs->log, QD_LOG_NOTICE, "Listening for HTTP on %s:%d (%s)", config->host, resolved_port, config->name);
        else
            qd_log(hs->log, QD_LOG_NOTICE, "Listening for HTTP on %s:%d", config->host, resolved_port);
    } else {
        qd_log(hs->log, QD_LOG_NOTICE, "Listening for HTTP on %s", config->host_port);
    }
    return;

  error:
    if (hl->listener->exit_on_error) {
        qd_log(hs->log, QD_LOG_CRITICAL, "Shutting down, required listener failed %s",
               config->host_port);
        exit(1);
    }
    qd_lws_listener_free(hl);
}

static void listener_close(qd_lws_listener_t *hl, qd_http_server_t *hs) {
    qd_server_config_t *config = &hl->listener->config;
    qd_log(hs->log, QD_LOG_NOTICE, "Stopped listening for HTTP on %s", config->host_port);
    lws_vhost_destroy(hl->vhost);
}

/*
 * LWS callback for un-promoted HTTP connections.
 * Note main HTTP file serving is handled by the "mount" struct below.
 */
static int callback_http(struct lws *wsi, enum lws_callback_reasons reason,
                         void *user, void *in, size_t len)
{
    /*
     * Modern LibWebSockets uses the .finalize callback on lws_context for cleanup
     */
#ifndef QD_HAVE_MODERN_LIBWEBSOCKETS
    switch (reason) {
    case LWS_CALLBACK_PROTOCOL_DESTROY:
        finalize_http(NULL, wsi_listener(wsi));
        break;
    default:
        break;
    }
#endif

    /* Do default HTTP handling for all the cases we don't care about. */
    return lws_callback_http_dummy(wsi, reason, user, in, len);
}

inline static void finalize_http(struct lws_vhost *vh /*unused*/, void *arg) {
    qd_lws_listener_t *listener = (qd_lws_listener_t*) arg;
    qd_lws_listener_free(listener);
}

/* Wake up a connection managed by the http server thread */
static void connection_wake(qd_connection_t *qd_conn)
{
    connection_t *c = qd_conn->context;
    if (c && qd_conn->listener->http) {
        qd_http_server_t *hs = qd_conn->listener->http->server;
        work_t w = { W_WAKE, c };
        work_push(hs, w);
    }
}

/**
 * Called on router worker thread
 */
static void handle_stats_results(void *context)
{
    stats_request_state_t* state = (stats_request_state_t*) context;
    if (state->wsi_deleted) {
        free(state);
    } else {
        qd_http_server_t *hs = state->server;
        if (hs) {
            work_t w = { W_HANDLE_STATS, state };
            work_push(hs, w);
        }
    }
}

/**
 * Called on http thread
 */
static void handle_stats_result_HT(stats_request_state_t* state)
{
    if (state->wsi_deleted) {
        free(state);
    } else {
        state->callback_completed = true;
        lws_callback_on_writable(state->wsi);
    }
}

typedef int (*int_metric) (qdr_global_stats_t *stats);
typedef struct metric_definition {
    const char* name;
    const char* type;
    int_metric value;
} metric_definition;

typedef struct allocator_metric_definition {
    const char* name;
    qd_alloc_stats_t *(*fn)(void);
} allocator_metric_definition;

static int stats_get_connections(qdr_global_stats_t *stats) { return stats->connections; }
static int stats_get_links(qdr_global_stats_t *stats) { return stats->links; }
static int stats_get_addrs(qdr_global_stats_t *stats) { return stats->addrs; }
static int stats_get_routers(qdr_global_stats_t *stats) { return stats->routers; }
static int stats_get_link_routes(qdr_global_stats_t *stats) { return stats->link_routes; }
static int stats_get_auto_links(qdr_global_stats_t *stats) { return stats->auto_links; }
static int stats_get_presettled_deliveries(qdr_global_stats_t *stats) { return stats->presettled_deliveries; }
static int stats_get_dropped_presettled_deliveries(qdr_global_stats_t *stats) { return stats->dropped_presettled_deliveries; }
static int stats_get_accepted_deliveries(qdr_global_stats_t *stats) { return stats->accepted_deliveries; }
static int stats_get_released_deliveries(qdr_global_stats_t *stats) { return stats->released_deliveries; }
static int stats_get_rejected_deliveries(qdr_global_stats_t *stats) { return stats->rejected_deliveries; }
static int stats_get_modified_deliveries(qdr_global_stats_t *stats) { return stats->modified_deliveries; }
static int stats_get_deliveries_ingress(qdr_global_stats_t *stats) { return stats->deliveries_ingress; }
static int stats_get_deliveries_egress(qdr_global_stats_t *stats) { return stats->deliveries_egress; }
static int stats_get_deliveries_transit(qdr_global_stats_t *stats) { return stats->deliveries_transit; }
static int stats_get_deliveries_ingress_route_container(qdr_global_stats_t *stats) { return stats->deliveries_ingress_route_container; }
static int stats_get_deliveries_egress_route_container(qdr_global_stats_t *stats) { return stats->deliveries_egress_route_container; }
static int stats_get_deliveries_delayed_1sec(qdr_global_stats_t *stats) { return stats->deliveries_delayed_1sec; }
static int stats_get_deliveries_delayed_10sec(qdr_global_stats_t *stats) { return stats->deliveries_delayed_10sec; }
static int stats_get_deliveries_stuck(qdr_global_stats_t *stats) { return stats->deliveries_stuck; }
static int stats_get_links_blocked(qdr_global_stats_t *stats) { return stats->links_blocked; }
static int stats_get_deliveries_redirected_to_fallback(qdr_global_stats_t *stats) { return stats->deliveries_redirected_to_fallback; }

qd_alloc_stats_t *alloc_stats_qd_bitmask_t(void);
qd_alloc_stats_t *alloc_stats_qd_buffer_t(void);
qd_alloc_stats_t *alloc_stats_qd_composed_field_t(void);
qd_alloc_stats_t *alloc_stats_qd_composite_t(void);
qd_alloc_stats_t *alloc_stats_qd_connection_t(void);
qd_alloc_stats_t *alloc_stats_qd_hash_handle_t(void);
qd_alloc_stats_t *alloc_stats_qd_hash_item_t(void);
qd_alloc_stats_t *alloc_stats_qd_iterator_t(void);
qd_alloc_stats_t *alloc_stats_qd_link_ref_t(void);
qd_alloc_stats_t *alloc_stats_qd_link_t(void);
qd_alloc_stats_t *alloc_stats_qd_listener_t(void);
qd_alloc_stats_t *alloc_stats_qd_log_entry_t(void);
qd_alloc_stats_t *alloc_stats_qd_management_context_t(void);
qd_alloc_stats_t *alloc_stats_qd_message_content_t(void);
qd_alloc_stats_t *alloc_stats_qd_message_t(void);
qd_alloc_stats_t *alloc_stats_qd_node_t(void);
qd_alloc_stats_t *alloc_stats_qd_parse_node_t(void);
qd_alloc_stats_t *alloc_stats_qd_parsed_field_t(void);
qd_alloc_stats_t *alloc_stats_qd_timer_t(void);
qd_alloc_stats_t *alloc_stats_qdr_action_t(void);
qd_alloc_stats_t *alloc_stats_qdr_address_config_t(void);
qd_alloc_stats_t *alloc_stats_qdr_address_t(void);
qd_alloc_stats_t *alloc_stats_qdr_connection_info_t(void);
qd_alloc_stats_t *alloc_stats_qdr_connection_t(void);
qd_alloc_stats_t *alloc_stats_qdr_connection_work_t(void);
qd_alloc_stats_t *alloc_stats_qdr_core_timer_t(void);
qd_alloc_stats_t *alloc_stats_qdr_delivery_cleanup_t(void);
qd_alloc_stats_t *alloc_stats_qdr_delivery_ref_t(void);
qd_alloc_stats_t *alloc_stats_qdr_delivery_t(void);
qd_alloc_stats_t *alloc_stats_qdr_field_t(void);
qd_alloc_stats_t *alloc_stats_qdr_general_work_t(void);
qd_alloc_stats_t *alloc_stats_qdr_link_ref_t(void);
qd_alloc_stats_t *alloc_stats_qdr_link_t(void);
qd_alloc_stats_t *alloc_stats_qdr_link_work_t(void);
qd_alloc_stats_t *alloc_stats_qdr_query_t(void);
qd_alloc_stats_t *alloc_stats_qdr_terminus_t(void);

static struct metric_definition metrics[] = {
    {"qdr_connections_total", "gauge", stats_get_connections},
    {"qdr_links_total", "gauge", stats_get_links},
    {"qdr_addresses_total", "gauge", stats_get_addrs},
    {"qdr_routers_total", "gauge", stats_get_routers},
    {"qdr_link_routes_total", "gauge", stats_get_link_routes},
    {"qdr_auto_links_total", "gauge", stats_get_auto_links},
    {"qdr_presettled_deliveries_total", "counter", stats_get_presettled_deliveries},
    {"qdr_dropped_presettled_deliveries_total", "counter", stats_get_dropped_presettled_deliveries},
    {"qdr_accepted_deliveries_total", "counter", stats_get_accepted_deliveries},
    {"qdr_released_deliveries_total", "counter", stats_get_released_deliveries},
    {"qdr_rejected_deliveries_total", "counter", stats_get_rejected_deliveries},
    {"qdr_modified_deliveries_total", "counter", stats_get_modified_deliveries},
    {"qdr_deliveries_ingress_total", "counter", stats_get_deliveries_ingress},
    {"qdr_deliveries_egress_total", "counter", stats_get_deliveries_egress},
    {"qdr_deliveries_transit_total", "counter", stats_get_deliveries_transit},
    {"qdr_deliveries_ingress_route_container_total", "counter", stats_get_deliveries_ingress_route_container},
    {"qdr_deliveries_egress_route_container_total", "counter", stats_get_deliveries_egress_route_container},
    {"qdr_deliveries_delayed_1sec_total", "counter", stats_get_deliveries_delayed_1sec},
    {"qdr_deliveries_delayed_10sec_total", "counter", stats_get_deliveries_delayed_10sec},
    {"qdr_deliveries_stuck_total", "gauge", stats_get_deliveries_stuck},
    {"qdr_links_blocked_total", "gauge", stats_get_links_blocked},
    {"qdr_deliveries_redirected_to_fallback_total", "counter", stats_get_deliveries_redirected_to_fallback}
};
static size_t metrics_length = sizeof(metrics)/sizeof(metrics[0]);

static struct allocator_metric_definition allocator_metrics[] = {
        {"qdr_allocator_qd_bitmask_t", alloc_stats_qd_bitmask_t},
        {"qdr_allocator_qd_buffer_t", alloc_stats_qd_buffer_t},
        {"qdr_allocator_qd_composed_field_t", alloc_stats_qd_composed_field_t},
        {"qdr_allocator_qd_composite_t", alloc_stats_qd_composite_t},
        {"qdr_allocator_qd_connection_t", alloc_stats_qd_connection_t},
        {"qdr_allocator_qd_hash_handle_t", alloc_stats_qd_hash_handle_t},
        {"qdr_allocator_qd_hash_item_t", alloc_stats_qd_hash_item_t},
        {"qdr_allocator_qd_iterator_t", alloc_stats_qd_iterator_t},
        {"qdr_allocator_qd_link_ref_t", alloc_stats_qd_link_ref_t},
        {"qdr_allocator_qd_link_t", alloc_stats_qd_link_t},
        {"qdr_allocator_qd_listener_t", alloc_stats_qd_listener_t},
        {"qdr_allocator_qd_log_entry_t", alloc_stats_qd_log_entry_t},
        {"qdr_allocator_qd_management_context_t", alloc_stats_qd_management_context_t},
        {"qdr_allocator_qd_message_content_t", alloc_stats_qd_message_content_t},
        {"qdr_allocator_qd_message_t", alloc_stats_qd_message_t},
        {"qdr_allocator_qd_node_t", alloc_stats_qd_node_t},
        {"qdr_allocator_qd_parse_node_t", alloc_stats_qd_parse_node_t},
        {"qdr_allocator_qd_parsed_field_t", alloc_stats_qd_parsed_field_t},
        {"qdr_allocator_qd_timer_t", alloc_stats_qd_timer_t},
        {"qdr_allocator_qdr_action_t", alloc_stats_qdr_action_t},
        {"qdr_allocator_qdr_address_config_t", alloc_stats_qdr_address_config_t},
        {"qdr_allocator_qdr_address_t", alloc_stats_qdr_address_t},
        {"qdr_allocator_qdr_connection_info_t", alloc_stats_qdr_connection_info_t},
        {"qdr_allocator_qdr_connection_t", alloc_stats_qdr_connection_t},
        {"qdr_allocator_qdr_connection_work_t", alloc_stats_qdr_connection_work_t},
        {"qdr_allocator_qdr_core_timer_t", alloc_stats_qdr_core_timer_t},
        {"qdr_allocator_qdr_delivery_cleanup_t", alloc_stats_qdr_delivery_cleanup_t},
        {"qdr_allocator_qdr_delivery_ref_t", alloc_stats_qdr_delivery_ref_t},
        {"qdr_allocator_qdr_delivery_t", alloc_stats_qdr_delivery_t},
        {"qdr_allocator_qdr_field_t", alloc_stats_qdr_field_t},
        {"qdr_allocator_qdr_general_work_t", alloc_stats_qdr_general_work_t},
        {"qdr_allocator_qdr_link_ref_t", alloc_stats_qdr_link_ref_t},
        {"qdr_allocator_qdr_link_t", alloc_stats_qdr_link_t},
        {"qdr_allocator_qdr_link_work_t", alloc_stats_qdr_link_work_t},
        {"qdr_allocator_qdr_query_t", alloc_stats_qdr_query_t},
        {"qdr_allocator_qdr_terminus_t", alloc_stats_qdr_terminus_t}
};
static size_t allocator_metrics_length = sizeof(allocator_metrics)/sizeof(allocator_metrics[0]);

#define ALLOC_DATA(S, F) ((allocator_field) {#F, (S!=NULL? S->F: 0)})

typedef struct allocator_field {
    const char* name;
    uint64_t value;
} allocator_field;

static bool write_stats(uint8_t **position, const uint8_t * const end, const char* name, const char* type, int value)
{
    //11 chars + type + 2*name + 20 chars for int
    // average metric name size is 30 bytes
    // average metric type size is 8 bytes
    // current number of metrics is 22
    // total metric buffer size = 22 * (11 + 8 + 2*30 + 20) = 2178
    size_t length = 11 + strlen(type) + strlen(name)*2 + 20;
    if (end - *position >= length) {
        *position += lws_snprintf((char*) *position, end - *position, "# TYPE %s %s\n", name, type);
        *position += lws_snprintf((char*) *position, end - *position, "%s %i\n", name, value);
        return true;
    } else {
        return false;
    }
}

static bool write_allocator_stats(uint8_t **position, const uint8_t * const end, const char* name, allocator_field field)
{
    // 30 chars (static) + 2*name + 2*field.name + 20 for int
    // average allocator metric name size is 54 bytes (name:field.name)
    // current number of metrics is 180
    // total allocator buffer size = 180 * (30 + 2*54 + 20) = 28440
    size_t length = 30 + strlen(name)*2 + strlen(field.name)*2 + 20;
    if (end - *position >= length) {
        *position += lws_snprintf((char*) *position, end - *position, "# TYPE %s:%s_bytes gauge\n", name, field.name);
        *position += lws_snprintf((char*) *position, end - *position, "%s:%s_bytes %"PRIu64"\n", name, field.name, field.value);
        return true;
    } else {
        return false;
    }
}

static bool write_metric(uint8_t **position, const uint8_t * const end, metric_definition* definition, qdr_global_stats_t* stats)
{
    return write_stats(position, end, definition->name, definition->type, definition->value(stats));
}

static bool write_allocator_metric(uint8_t **position, const uint8_t * const end, allocator_metric_definition* definition)
{
    qd_alloc_stats_t *allocator_stats = definition->fn();
    if (!write_allocator_stats(position, end, definition->name, ALLOC_DATA(allocator_stats, total_alloc_from_heap))) return false;
    if (!write_allocator_stats(position, end, definition->name, ALLOC_DATA(allocator_stats, total_free_to_heap))) return false;
    if (!write_allocator_stats(position, end, definition->name, ALLOC_DATA(allocator_stats, held_by_threads))) return false;
    if (!write_allocator_stats(position, end, definition->name, ALLOC_DATA(allocator_stats, batches_rebalanced_to_threads))) return false;
    if (!write_allocator_stats(position, end, definition->name, ALLOC_DATA(allocator_stats, batches_rebalanced_to_global))) return false;
    return true;
}

static int add_header_by_name(struct lws *wsi, const char* name, const char* value, uint8_t** position, uint8_t* end)
{
    return lws_add_http_header_by_name(wsi, (unsigned char*) name, (unsigned char*) value, strlen(value), position, end);
}

static int callback_metrics(struct lws *wsi, enum lws_callback_reasons reason,
                               void *user, void *in, size_t len)
{
    qd_http_server_t *hs = wsi_server(wsi);
    stats_t *stats = (stats_t*) user;
    // rationale for buffer size is explained at write_stats and write_allocator_stats
    uint8_t buffer[LWS_PRE + 30618];
    uint8_t *start = &buffer[LWS_PRE], *position = start, *end = &buffer[sizeof(buffer) - LWS_PRE - 1];

    switch (reason) {

    case LWS_CALLBACK_HTTP: {
        stats->context = NEW(stats_request_state_t);
        ZERO(stats->context);
        stats->context->wsi = wsi;
        stats->context->server = hs;
        //request stats from core thread
        qdr_request_global_stats(hs->core, &stats->context->stats, handle_stats_results, (void*) stats->context);
        return 0;
    }

    case LWS_CALLBACK_HTTP_WRITEABLE: {
        //encode stats into buffer
        if (!stats->headers_sent) {
            if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &position, end)
                || add_header_by_name(wsi, "content-type:", "text/plain", &position, end)
                || add_header_by_name(wsi, "connection:", "close", &position, end))
                return 1;
            if (lws_finalize_http_header(wsi, &position, end))
                return 1;
            stats->headers_sent = true;
        }

        while (stats->current < metrics_length) {
            if (write_metric(&position, end, &metrics[stats->current], &stats->context->stats)) {
                stats->current++;
                qd_log(hs->log, QD_LOG_DEBUG, "wrote metric %lu of %lu", stats->current, metrics_length);
            } else {
                qd_log(hs->log, QD_LOG_WARNING, "insufficient space in buffer");
                break;
            }
        }

        int alloc_cur = 0;
        while (alloc_cur < allocator_metrics_length) {
            if (write_allocator_metric(&position, end, &allocator_metrics[alloc_cur])) {
                qd_log(hs->log, QD_LOG_DEBUG, "wrote allocator metric %i of %lu", alloc_cur, allocator_metrics_length);
                alloc_cur++;
            } else {
                qd_log(hs->log, QD_LOG_WARNING, "insufficient space in buffer");
                break;
            }
        }
        int n = (stats->current < metrics_length) || (alloc_cur < allocator_metrics_length) ? LWS_WRITE_HTTP : LWS_WRITE_HTTP_FINAL;

        //write buffer
        size_t available = position - start;
        if (lws_write(wsi, (unsigned char*) start, available, n) != available)
            return 1;
        if (n == LWS_WRITE_HTTP_FINAL) {
            if (lws_http_transaction_completed(wsi)) return -1;
        } else {
            lws_callback_on_writable(wsi);
        }
        return 0;
    }

    case LWS_CALLBACK_CLOSED: {
        stats->context->wsi_deleted = true;
        if (stats->context->callback_completed) {
            free(stats->context);
        }
    }

    default:
        return 0;
    }
}

static int callback_healthz(struct lws *wsi, enum lws_callback_reasons reason,
                               void *user, void *in, size_t len)
{
    qd_http_server_t *hs = wsi_server(wsi);
    stats_t *stats = (stats_t*) user;
    uint8_t buffer[LWS_PRE + 2048];
    uint8_t *start = &buffer[LWS_PRE], *position = start, *end = &buffer[sizeof(buffer) - LWS_PRE - 1];

    switch (reason) {

    case LWS_CALLBACK_HTTP: {
        stats->context = NEW(stats_request_state_t);
        ZERO(stats->context);
        stats->context->wsi = wsi;
        stats->context->server = hs;
        //make dummy request for stats (pass in null ptr); this still exercises the
        //path through core thread and back through callback on io thread which is
        //a reasonable initial liveness check
        qdr_request_global_stats(hs->core, 0, handle_stats_results, (void*) stats->context);
        return 0;
    }

    case LWS_CALLBACK_HTTP_WRITEABLE: {
        //encode stats into buffer
        if (!stats->headers_sent) {
            if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &position, end)
                || add_header_by_name(wsi, "content-type:", "text/plain", &position, end)
                || lws_add_http_header_content_length(wsi, 3, &position, end))
                return 1;
            if (lws_finalize_http_header(wsi, &position, end))
                return 1;
            stats->headers_sent = true;
        }
        position += lws_snprintf((char*) position, end - position, "OK\n");

        int n = LWS_WRITE_HTTP_FINAL;
        //write buffer
        size_t available = position - start;
	if (lws_write(wsi, (unsigned char*) start, available, n) != available)
            return 1;
        else if (lws_http_transaction_completed(wsi))
            return -1;
        else return 0;
    }

    case LWS_CALLBACK_CLOSED: {
        stats->context->wsi_deleted = true;
        if (stats->context->callback_completed) {
            free(stats->context);
        }
    }

    default:
        return 0;
    }
}

/* Callbacks for promoted AMQP over WS connections. */
static int callback_amqpws(struct lws *wsi, enum lws_callback_reasons reason,
                           void *user, void *in, size_t len)
{
    qd_http_server_t *hs = wsi_server(wsi);
    connection_t *c = (connection_t*)user;

    switch (reason) {

    case LWS_CALLBACK_ESTABLISHED: {
        /* Upgrade accepted HTTP connection to AMQPWS */
        memset(c, 0, sizeof(*c));
        c->wsi = wsi;
        qd_lws_listener_t *hl = wsi_listener(wsi);
        if (hl == NULL || !hl->listener->config.websockets) {
            return unexpected_close(c->wsi, "cannot-upgrade");
        }
        c->qd_conn = qd_server_connection(hs->server, &hl->listener->config);
        if (c->qd_conn == NULL) {
            return unexpected_close(c->wsi, "out-of-memory");
        }
        c->qd_conn->context = c;
        c->qd_conn->wake = connection_wake;
        c->qd_conn->listener = hl->listener;
        lws_get_peer_simple(wsi, c->qd_conn->rhost, sizeof(c->qd_conn->rhost));
        int err = pn_connection_driver_init(&c->driver, c->qd_conn->pn_conn, NULL);
        if (err) {
            return unexpected_close(c->wsi, pn_code(err));
        }
        strncpy(c->qd_conn->rhost_port, c->qd_conn->rhost, sizeof(c->qd_conn->rhost_port));
        qd_log(hs->log, QD_LOG_DEBUG,
               "[%"PRIu64"] upgraded HTTP connection from %s to AMQPWS",
               qd_connection_connection_id(c->qd_conn), qd_connection_name(c->qd_conn));
        return handle_events(c);
    }

    case LWS_CALLBACK_SERVER_WRITEABLE: {
        if (handle_events(c)) return -1;
        pn_bytes_t dbuf = pn_connection_driver_write_buffer(&c->driver);
        if (dbuf.size) {
            /* lws_write() demands LWS_PRE bytes of free space before the data,
             * so we must copy from the driver's buffer to larger temporary wbuf
             */
            buffer_set_size(&c->wbuf, LWS_PRE + dbuf.size);
            if (c->wbuf.start == NULL) {
                return unexpected_close(c->wsi, "out-of-memory");
            }
            unsigned char* buf = (unsigned char*)c->wbuf.start + LWS_PRE;
            memcpy(buf, dbuf.start, dbuf.size);
            ssize_t wrote = lws_write(wsi, buf, dbuf.size, LWS_WRITE_BINARY);
            if (wrote < 0) {
                pn_connection_driver_write_close(&c->driver);
                return unexpected_close(c->wsi, "write-error");
            } else {
                pn_connection_driver_write_done(&c->driver, wrote);
            }
        }
        return handle_events(c);
    }

    case LWS_CALLBACK_RECEIVE: {
        while (len > 0) {
            if (handle_events(c)) return -1;
            pn_rwbytes_t dbuf = pn_connection_driver_read_buffer(&c->driver);
            if (dbuf.size == 0) {
                return unexpected_close(c->wsi, "unexpected-data");
            }
            size_t copy = (len < dbuf.size) ? len : dbuf.size;
            memcpy(dbuf.start, in, copy);
            pn_connection_driver_read_done(&c->driver, copy);
            len -= copy;
            in = (char*)in + copy;
        }
        return handle_events(c);
    }

    case LWS_CALLBACK_USER: {
        pn_timestamp_t next_tick = pn_transport_tick(c->driver.transport, hs->now);
        if (next_tick && next_tick > hs->now && next_tick < hs->next_tick) {
            hs->next_tick = next_tick;
        }
        return handle_events(c);
    }

    case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: {
        pn_connection_driver_read_close(&c->driver);
        return handle_events(c);
    }

    case LWS_CALLBACK_CLOSED: {
        if (c->driver.transport) {
            pn_connection_driver_close(&c->driver);
            handle_events(c);
        }
        pn_connection_driver_destroy(&c->driver);
        free(c->wbuf.start);
        return -1;
    }

    default:
        return 0;
    }
}

#define DEFAULT_TICK 1000

static void* http_thread_run(void* v) {
    qd_http_server_t *hs = v;
    qd_log(hs->log, QD_LOG_INFO, "HTTP server thread running");
    int result = 0;
    while(result >= 0) {
        /* Send a USER event to run transport ticks, may decrease hs->next_tick. */
        hs->now = qd_timer_now();
        hs->next_tick = hs->now + DEFAULT_TICK;
        lws_callback_all_protocol(hs->context, &protocols[1], LWS_CALLBACK_USER);
        lws_callback_all_protocol(hs->context, &protocols[2], LWS_CALLBACK_USER);
        pn_millis_t timeout = (hs->next_tick > hs->now) ? hs->next_tick - hs->now : 1;
        result = lws_service(hs->context, timeout);

        /* Process any work items on the queue */
        for (work_t w = work_pop(hs); w.type != W_NONE; w = work_pop(hs)) {
            switch (w.type) {
            case W_NONE:
                break;
            case W_STOP:
                result = -1;
                break;
            case W_LISTEN:
                listener_start((qd_lws_listener_t*)w.value, hs);
                break;
            case W_CLOSE:
                listener_close((qd_lws_listener_t*)w.value, hs);
                break;
            case W_HANDLE_STATS:
                handle_stats_result_HT((stats_request_state_t*) w.value);
                break;
            case W_WAKE: {
                connection_t *c = w.value;
                pn_collector_put(c->driver.collector, PN_OBJECT, c->driver.connection,
                                 PN_CONNECTION_WAKE);
                handle_events(c);
                break;
            }
            }
        }
    }
    qd_log(hs->log, QD_LOG_INFO, "HTTP server thread exit");
    return NULL;
}

void qd_http_server_stop(qd_http_server_t *hs) {
    if (!hs) return;
    if (hs->thread) {
        /* Thread safe, stop via work queue then clean up */
        work_t work = { W_STOP, NULL };
        work_push(hs, work);
        sys_thread_join(hs->thread);
        sys_thread_free(hs->thread);
        hs->thread = NULL;
    }
}

void qd_http_server_free(qd_http_server_t *hs) {
    if (!hs) return;
    qd_http_server_stop(hs);
    work_queue_destroy(&hs->work);
    if (hs->context) lws_context_destroy(hs->context);
    free(hs);
}

qd_http_server_t *qd_http_server(qd_server_t *s, qd_log_source_t *log) {
    log_init();
    qd_http_server_t *hs = calloc(1, sizeof(*hs));
    if (hs) {
        work_queue_init(&hs->work);
        struct lws_context_creation_info info = {0};
        info.gid = info.uid = -1;
        info.user = hs;
        info.server_string = QD_CONNECTION_PROPERTY_PRODUCT_VALUE;
        info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
            LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME |
            LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
        info.max_http_header_pool = 32;
        info.timeout_secs = 1;

        hs->context = lws_create_context(&info);
        hs->server = s;
        hs->log = log;              /* For messages from this file */
        hs->core = 0; // not yet available
        if (!hs->context) {
            qd_log(hs->log, QD_LOG_CRITICAL, "No memory starting HTTP server");
            qd_http_server_free(hs);
            hs = NULL;
        }
    }
    return hs;
}

/* Thread safe calls that put items on work queue */

qd_lws_listener_t *qd_http_server_listen(qd_http_server_t *hs, qd_listener_t *li)
{
    hs->core = qd_dispatch_router_core(qd_server_dispatch(hs->server));
    sys_mutex_lock(hs->work.lock);
    if (!hs->thread) {
        hs->thread = sys_thread(http_thread_run, hs);
    }
    bool ok = hs->thread;
    sys_mutex_unlock(hs->work.lock);
    if (!ok) return NULL;

    qd_lws_listener_t *hl = qd_lws_listener(hs, li);
    if (hl) {
        work_t w = { W_LISTEN, hl };
        work_push(hs, w);
    }
    return hl;
}

void qd_lws_listener_close(qd_lws_listener_t *hl)
{
    work_t w = { W_CLOSE, hl };
    work_push(hl->server, w);
}

static qd_http_server_t *wsi_server(struct lws *wsi) {
    return (qd_http_server_t*)lws_context_user(lws_get_context(wsi));
}

static qd_lws_listener_t *wsi_listener(struct lws *wsi) {
    qd_lws_listener_t *hl = NULL;
    struct lws_vhost *vhost = lws_get_vhost(wsi);
    if (vhost) {                /* Get qd_lws_listener from vhost data */
        void *vp = lws_protocol_vh_priv_get(vhost, &protocols[0]);
        memcpy(&hl, vp, sizeof(hl));
    }
    return hl;
}

static qd_log_source_t *wsi_log(struct lws *wsi) {
    return wsi_server(wsi)->log;
}
