/* ====================================================================
 *    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 "serf.h"
#include "serf_private.h"
#include "serf_bucket_util.h"

/* TODO: don't use SOCK[_MSG]_VERBOSE directly, but get a log category in
   from the config object. */

typedef struct log_wrapped_context_t {
    const serf_bucket_type_t *old_type;
    const char *prefix;
    serf_config_t *config;
} log_wrapped_context_t;

/* Extended serf_bucket_t. */
typedef struct serf_log_wrapped_bucket_t {
    /* This must be the first member to ensure that this bucket can be cast
       to a serf_bucket_t */
    serf_bucket_t wrapped_bkt;

    /* stored data for the log wrapper */
    log_wrapped_context_t *more_data;
} serf_log_wrapped_bucket_t;


static apr_status_t
serf_log_wrapped_readline(serf_bucket_t *bucket,
                          int acceptable, int *found,
                          const char **data, apr_size_t *len)
{
    serf_log_wrapped_bucket_t *lwbkt = (serf_log_wrapped_bucket_t *)bucket;
    log_wrapped_context_t *ctx = lwbkt->more_data;

    apr_status_t status = ctx->old_type->readline(bucket, acceptable, found,
                                                  data, len);

    if (SERF_BUCKET_READ_ERROR(status))
        serf__log(LOGLVL_ERROR, LOGCOMP_CONN, ctx->prefix, ctx->config,
                  "Error %d while reading.\n", status);

    if (*len) {
        serf__log(LOGLVL_DEBUG, LOGCOMP_CONN, ctx->prefix, ctx->config,
                  "--- %"APR_SIZE_T_FMT" bytes. --\n", *len);
        serf__log(LOGLVL_DEBUG, LOGCOMP_RAWMSG, ctx->prefix, ctx->config,
                  "%.*s\n", (int)*len, *data);
    }

    return status;
}

static apr_status_t
serf_log_wrapped_read_iovec(serf_bucket_t *bucket,
                            apr_size_t requested,
                            int vecs_size,
                            struct iovec *vecs,
                            int *vecs_used)
{
    serf_log_wrapped_bucket_t *lwbkt = (serf_log_wrapped_bucket_t *)bucket;
    log_wrapped_context_t *ctx = lwbkt->more_data;
    apr_size_t len;
    int i;

    apr_status_t status = ctx->old_type->read_iovec(bucket, requested, vecs_size,
                                                    vecs, vecs_used);

    if (SERF_BUCKET_READ_ERROR(status))
        serf__log(LOGLVL_ERROR, LOGCOMP_CONN, ctx->prefix, ctx->config,
                  "Error %d while reading.\n", status);

    for (i = 0, len = 0; i < *vecs_used; i++)
        len += vecs[i].iov_len;
    serf__log(LOGLVL_DEBUG, LOGCOMP_CONN, ctx->prefix, ctx->config,
              "--- %"APR_SIZE_T_FMT" bytes. --\n", len);

    for (i = 0; i < *vecs_used; i++) {
        serf__log_nopref(LOGLVL_DEBUG, LOGCOMP_RAWMSG, ctx->config,
                         "%.*s", (int)vecs[i].iov_len, vecs[i].iov_base);
    }
    serf__log_nopref(LOGLVL_DEBUG, LOGCOMP_RAWMSG, ctx->config, "\n");

    return status;
}

static apr_status_t
serf_log_wrapped_read(serf_bucket_t *bucket, apr_size_t requested,
                      const char **data, apr_size_t *len)
{
    serf_log_wrapped_bucket_t *lwbkt = (serf_log_wrapped_bucket_t *)bucket;
    log_wrapped_context_t *ctx = lwbkt->more_data;

    apr_status_t status = ctx->old_type->read(bucket, requested, data, len);

    if (SERF_BUCKET_READ_ERROR(status))
        serf__log(LOGLVL_ERROR, LOGCOMP_CONN, ctx->prefix, ctx->config,
                  "Error %d while reading.\n", status);
    else if (*len) {
        serf__log(LOGLVL_DEBUG, LOGCOMP_CONN, ctx->prefix, ctx->config,
                  "--- %"APR_SIZE_T_FMT" bytes. --\n", *len);
        serf__log(LOGLVL_DEBUG, LOGCOMP_RAWMSG, ctx->prefix, ctx->config,
                  "%.*s\n", (int)*len, *data);
    }

    return status;
}

static void serf_log_wrapped_destroy(serf_bucket_t *bucket)
{
    serf_log_wrapped_bucket_t *lwbkt = (serf_log_wrapped_bucket_t *)bucket;
    const serf_bucket_type_t *bkt_type = lwbkt->more_data->old_type;

    serf_bucket_mem_free(bucket->allocator, (void*)bucket->type);
    serf_bucket_mem_free(bucket->allocator, lwbkt->more_data);
    bkt_type->destroy(bucket);
}

static apr_status_t serf_log_wrapped_set_config(serf_bucket_t *bucket,
                                                serf_config_t *config)
{
    serf_log_wrapped_bucket_t *lwbkt = (serf_log_wrapped_bucket_t *)bucket;
    log_wrapped_context_t *ctx = lwbkt->more_data;

    ctx->config = config;

    return ctx->old_type->set_config(bucket, config);
}

serf_bucket_t *serf__bucket_log_wrapper_create(serf_bucket_t *wrapped,
                                               const char *prefix,
                                               serf_bucket_alloc_t *alloc)
{
    /* ### This code currently breaks SERF_BUCKET_IS_XXXX() on the bucket.
           So to avoid many false warnings we disable it when using
           SERF_DEBUG_BUCKET_USE
     */
#if defined(SERF_LOGGING_ENABLED) && !defined(SERF_DEBUG_BUCKET_USE)
    serf_log_wrapped_bucket_t *bkt = serf_bucket_mem_alloc(alloc, sizeof(*bkt));
    log_wrapped_context_t *ctx = serf_bucket_mem_alloc(alloc, sizeof(*ctx));
    serf_bucket_type_t *bkt_type = serf_bucket_mem_alloc(alloc, sizeof(*bkt_type));

    /* Construct the new bucket type based on the wrapped bucket type, but
       replace all read functions with the logging wrappers. */
    bkt_type->name = wrapped->type->name;
    bkt_type->peek = wrapped->type->peek;
    /* These read functions are not used by serf, so no need to add logging. */
    bkt_type->read_for_sendfile = wrapped->type->read_for_sendfile;
    if (serf_get_type(wrapped, 2) != NULL) {
        bkt_type->read_bucket = serf_buckets_are_v2;
        bkt_type->read_bucket_v2 = wrapped->type->read_bucket_v2;
        bkt_type->get_remaining = wrapped->type->get_remaining;
    } else {
        bkt_type->read_bucket = wrapped->type->read_bucket;
    }

    /* Wrap these functions */
    bkt_type->destroy = serf_log_wrapped_destroy;
    bkt_type->read = serf_log_wrapped_read;
    bkt_type->readline = serf_log_wrapped_readline;
    bkt_type->read_iovec = serf_log_wrapped_read_iovec;
    bkt_type->set_config = serf_log_wrapped_set_config;

    ctx->old_type = wrapped->type;
    ctx->prefix = prefix;
    ctx->config = NULL;

    /* Construct the new extended bucket. */
    bkt->wrapped_bkt.type = bkt_type;
    bkt->wrapped_bkt.data = wrapped->data;
    bkt->wrapped_bkt.allocator = wrapped->allocator;
    bkt->more_data = ctx;

    /* We have created a new extended bucket and copied over the data from the
       wrapped bucket, so we can delete the wrapped bucket now. */
    serf_default_destroy(wrapped);

    return (serf_bucket_t *)bkt;
#else
    return wrapped;
#endif
}
