/* ====================================================================
 *    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", *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", 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", *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
}
