/* ====================================================================
 *    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 <apr_pools.h>
#include <apr_poll.h>
#include <apr_version.h>

#include "serf.h"
#include "serf_bucket_util.h"

#include "serf_private.h"

/**
 * Callback function (implements serf_progress_t). Takes a number of bytes
 * read @a read and bytes written @a written, adds those to the total for this
 * context and notifies an interested party (if any).
 */
void serf__context_progress_delta(
    void *progress_baton,
    apr_off_t read,
    apr_off_t written)
{
    serf_context_t *ctx = progress_baton;

    ctx->progress_read += read;
    ctx->progress_written += written;

    if (ctx->progress_func)
        ctx->progress_func(ctx->progress_baton,
                           ctx->progress_read,
                           ctx->progress_written);
}


/* Check for dirty connections and update their pollsets accordingly. */
static apr_status_t check_dirty_pollsets(serf_context_t *ctx)
{
    int i;

    /* if we're not dirty, return now. */
    if (!ctx->dirty_pollset) {
        return APR_SUCCESS;
    }

    for (i = ctx->conns->nelts; i--; ) {
        serf_connection_t *conn = GET_CONN(ctx, i);
        apr_status_t status;

        /* if this connection isn't dirty, skip it. */
        if (!conn->io.dirty_conn) {
            continue;
        }

        /* reset this connection's flag before we update. */
        conn->io.dirty_conn = false;

        if ((status = serf__conn_update_pollset(conn)) != APR_SUCCESS)
            return status;
    }

    for (i = ctx->incomings->nelts; i--; ) {
        serf_incoming_t *incoming = GET_INCOMING(ctx, i);
        apr_status_t status;

        if (!incoming->io.dirty_conn) {
            continue;
        }

        incoming->io.dirty_conn = false;

        if ((status = serf__incoming_update_pollset(incoming)) != APR_SUCCESS)
            return status;
    }

    /* reset our context flag now */
    ctx->dirty_pollset = false;

    return APR_SUCCESS;
}


static apr_status_t pollset_add(void *user_baton,
                                apr_pollfd_t *pfd,
                                void *serf_baton)
{
    serf_pollset_t *s = (serf_pollset_t*)user_baton;
    pfd->client_data = serf_baton;
    return apr_pollset_add(s->pollset, pfd);
}

static apr_status_t pollset_rm(void *user_baton,
                               apr_pollfd_t *pfd,
                               void *serf_baton)
{
    serf_pollset_t *s = (serf_pollset_t*)user_baton;
    pfd->client_data = serf_baton;
    return apr_pollset_remove(s->pollset, pfd);
}


void serf_config_proxy(serf_context_t *ctx,
                       apr_sockaddr_t *address)
{
    ctx->proxy_address = address;
}


void serf_config_credentials_callback(serf_context_t *ctx,
                                      serf_credentials_callback_t cred_cb)
{
    ctx->cred_cb = cred_cb;
}


void serf_config_authn_types(serf_context_t *ctx,
                             int authn_types)
{
    ctx->authn_types = authn_types;
}


serf_context_t *serf_context_create_ex(
    void *user_baton,
    serf_socket_add_t addf,
    serf_socket_remove_t rmf,
    apr_pool_t *pool)
{
    serf_context_t *ctx = apr_pcalloc(pool, sizeof(*ctx));

    ctx->pool = pool;

    if (user_baton != NULL) {
        ctx->pollset_baton = user_baton;
        ctx->pollset_add = addf;
        ctx->pollset_rm = rmf;
    }
    else {
        /* build the pollset with a (default) number of connections */
        serf_pollset_t *ps = apr_pcalloc(pool, sizeof(*ps));

        /* ### TODO: As of APR 1.4.x apr_pollset_create_ex can return a status
           ### other than APR_SUCCESS, so we should handle it.
           ### Probably move creation of the pollset to later when we have
           ### the possibility of returning status to the caller.
         */
#ifdef BROKEN_WSAPOLL
        /* APR 1.4.x switched to using WSAPoll() on Win32, but it does not
         * properly handle errors on a non-blocking sockets (such as
         * connecting to a server where no listener is active).
         *
         * So, sadly, we must force using select() on Win32.
         *
         * http://mail-archives.apache.org/mod_mbox/apr-dev/201105.mbox/%3CBANLkTin3rBCecCBRvzUA5B-14u-NWxR_Kg@mail.gmail.com%3E
         */
        (void) apr_pollset_create_ex(&ps->pollset, MAX_CONN, pool, 0,
                                     APR_POLLSET_SELECT);
#else
        (void) apr_pollset_create(&ps->pollset, MAX_CONN, pool, 0);
#endif
        ctx->pollset_baton = ps;
        ctx->pollset_add = pollset_add;
        ctx->pollset_rm = pollset_rm;
    }

    /* default to a single connection since that is the typical case */
    ctx->conns = apr_array_make(pool, 1, sizeof(serf_connection_t *));

    /* and we typically have no servers */
    ctx->incomings = apr_array_make(pool, 0, sizeof(serf_incoming_t *));

    /* Initialize progress status */
    ctx->progress_read = 0;
    ctx->progress_written = 0;

    ctx->authn_types = SERF_AUTHN_ALL;
    ctx->server_authn_info = apr_hash_make(pool);

    /* Assume returned status is APR_SUCCESS */
    serf__config_store_init(ctx);

    serf__config_store_create_ctx_config(ctx, &ctx->config);

    serf__log_init(ctx);

    return ctx;
}


serf_context_t *serf_context_create(apr_pool_t *pool)
{
    return serf_context_create_ex(NULL, NULL, NULL, pool);
}

apr_status_t serf_context_prerun(serf_context_t *ctx)
{
    apr_status_t status = APR_SUCCESS;
    if ((status = serf__open_connections(ctx)) != APR_SUCCESS)
        return status;

    if ((status = check_dirty_pollsets(ctx)) != APR_SUCCESS)
        return status;
    return status;
}


apr_status_t serf_event_trigger(
    serf_context_t *s,
    void *serf_baton,
    const apr_pollfd_t *desc)
{
    apr_status_t status = APR_SUCCESS;
    serf_io_baton_t *io = serf_baton;

    if (io->type == SERF_IO_CONN) {
        serf_connection_t *conn = io->u.conn;

        status = serf__process_connection(conn, desc->rtnevents);

        if (status) {
            return status;
        }
    }
    else if (io->type == SERF_IO_LISTENER) {
        serf_listener_t *l = io->u.listener;

        status = serf__process_listener(l);

        if (status) {
            return status;
        }
    }
    else if (io->type == SERF_IO_CLIENT) {
        serf_incoming_t *c = io->u.client;

        status = serf__process_client(c, desc->rtnevents);

        if (status) {
            return status;
        }
    }
    return status;
}


apr_status_t serf_context_run(
    serf_context_t *ctx,
    apr_short_interval_time_t duration,
    apr_pool_t *pool)
{
    apr_status_t status;
    apr_int32_t num;
    const apr_pollfd_t *desc;
    serf_pollset_t *ps = (serf_pollset_t*)ctx->pollset_baton;

    if ((status = serf_context_prerun(ctx)) != APR_SUCCESS) {
        return status;
    }

    if ((status = apr_pollset_poll(ps->pollset, duration, &num,
                                   &desc)) != APR_SUCCESS) {
        /* EINTR indicates a handled signal happened during the poll call,
           ignore, the application can safely retry. */
        if (APR_STATUS_IS_EINTR(status))
            return APR_SUCCESS;

        /* ### do we still need to dispatch stuff here?
           ### look at the potential return codes. map to our defined
           ### return values? ...
        */

        /* Use the strict documented error for poll timeouts, to allow proper
           handling of the other timeout types when returned from
           serf_event_trigger */
        if (APR_STATUS_IS_TIMEUP(status))
            return APR_TIMEUP; /* Return the documented error */
        return status;
    }

    while (num--) {
        serf_io_baton_t *io  = desc->client_data;

        status = serf_event_trigger(ctx, io, desc);
        if (status) {
            /* Don't return APR_TIMEUP as a connection error, as our caller
               will use that as a trigger to call us again */
            if (APR_STATUS_IS_TIMEUP(status))
                status = SERF_ERROR_CONNECTION_TIMEDOUT;
            return status;
        }

        desc++;
    }

    return APR_SUCCESS;
}


void serf_context_set_progress_cb(
    serf_context_t *ctx,
    const serf_progress_t progress_func,
    void *progress_baton)
{
    ctx->progress_func = progress_func;
    ctx->progress_baton = progress_baton;
}


serf_bucket_t *serf_context_bucket_socket_create(
    serf_context_t *ctx,
    apr_socket_t *skt,
    serf_bucket_alloc_t *allocator)
{
    serf_bucket_t *bucket = serf_bucket_socket_create(skt, allocator);

    bucket = serf__bucket_log_wrapper_create(bucket, "receiving raw",
                                             allocator);

    /* Use serf's default bytes read/written callback */
    serf_bucket_socket_set_read_progress_cb(bucket,
                                            serf__context_progress_delta,
                                            ctx);

    return bucket;
}


/* ### this really ought to go somewhere else, but... meh.  */
void serf_lib_version(int *major, int *minor, int *patch)
{
    *major = SERF_MAJOR_VERSION;
    *minor = SERF_MINOR_VERSION;
    *patch = SERF_PATCH_VERSION;
}


const char *serf_error_string(apr_status_t errcode)
{
    switch (errcode)
    {
    case SERF_ERROR_CLOSING:
        return "The connection is closing";
    case SERF_ERROR_REQUEST_LOST:
        return "A request has been lost";
    case SERF_ERROR_WAIT_CONN:
        return "The connection is blocked, pending further action";
    case SERF_ERROR_DECOMPRESSION_FAILED:
        return "An error occurred during decompression";
    case SERF_ERROR_BAD_HTTP_RESPONSE:
        return "The server sent an improper HTTP response";
    case SERF_ERROR_TRUNCATED_HTTP_RESPONSE:
        return "The server sent a truncated HTTP response body.";
    case SERF_ERROR_ABORTED_CONNECTION:
        return "The server unexpectedly closed the connection.";
    case SERF_ERROR_LINE_TOO_LONG:
        return "The line too long";
    case SERF_ERROR_STATUS_LINE_TOO_LONG:
        return "The HTTP response status line too long";
    case SERF_ERROR_RESPONSE_HEADER_TOO_LONG:
        return "The HTTP response header too long";
    case SERF_ERROR_CONNECTION_TIMEDOUT:
        return "The connection timed out";
    case SERF_ERROR_TRUNCATED_STREAM:
        return "The stream returned less data than was expected";
    case SERF_ERROR_EMPTY_STREAM:
        return "The stream is empty";
    case SERF_ERROR_EMPTY_READ:
        return "A successfull read of nothing occured";

    case SERF_ERROR_SSL_COMM_FAILED:
        return "An error occurred during SSL communication";
    case SERF_ERROR_SSL_SETUP_FAILED:
        return "An error occurred during SSL setup";
    case SERF_ERROR_SSL_CERT_FAILED:
        return "An SSL certificate related error occurred ";
    case SERF_ERROR_SSL_OCSP_RESPONSE_CERT_REVOKED:
        return "An OCSP responder declared an SSL certificate is revoked";
    case SERF_ERROR_SSL_OCSP_RESPONSE_CERT_UNKNOWN:
        return "An OCSP responder declared an SSL certificate is unknown";
    case SERF_ERROR_SSL_OCSP_RESPONSE_INVALID:
        return "An OCSP responder returned an invalid response";

    case SERF_ERROR_AUTHN_FAILED:
        return "An error occurred during authentication";
    case SERF_ERROR_AUTHN_NOT_SUPPORTED:
        return "The requested authentication type(s) are not supported";
    case SERF_ERROR_AUTHN_MISSING_ATTRIBUTE:
        return "An authentication attribute is missing";
    case SERF_ERROR_AUTHN_INITALIZATION_FAILED:
        return "Initialization of an authentication type failed";
    case SERF_ERROR_AUTHN_CREDENTIALS_REJECTED:
        return "The user credentials were rejected by the server";
    case SERF_ERROR_SSLTUNNEL_SETUP_FAILED:
        return "The proxy server returned an error while setting up the "
               "SSL tunnel.";

    /* HTTP2 protocol errors */
    case SERF_ERROR_HTTP2_NO_ERROR:
        return "HTTP2: Graceful shutdown";
    case SERF_ERROR_HTTP2_PROTOCOL_ERROR:
        return "HTTP2 protocol error detected";
    case SERF_ERROR_HTTP2_INTERNAL_ERROR:
        return "HTTP2 internal error";
    case SERF_ERROR_HTTP2_FLOW_CONTROL_ERROR:
        return "HTTP2 flow control limits exceeded";
    case SERF_ERROR_HTTP2_SETTINGS_TIMEOUT:
        return "HTTP2 settings not acknowledged";
    case SERF_ERROR_HTTP2_STREAM_CLOSED:
        return "HTTP2 frame received for closed stream";
    case SERF_ERROR_HTTP2_FRAME_SIZE_ERROR:
        return "HTTP2 frame size incorrect";
    case SERF_ERROR_HTTP2_REFUSED_STREAM:
        return "HTTP2 stream not processed";
    case SERF_ERROR_HTTP2_CANCEL:
        return "HTTP2 stream cancelled";
    case SERF_ERROR_HTTP2_COMPRESSION_ERROR:
        return "HTTP2 compression state not updated";
    case SERF_ERROR_HTTP2_CONNECT_ERROR:
        return "TCP connection error for HTTP2 connect method";
    case SERF_ERROR_HTTP2_ENHANCE_YOUR_CALM:
        return "HTTP2 processing capacity exceeded";
    case SERF_ERROR_HTTP2_INADEQUATE_SECURITY:
        return "HTTP2 negotiated TLS parameters not acceptable";
    case SERF_ERROR_HTTP2_HTTP_1_1_REQUIRED:
        return "HTTP 1.1 is required for this request";
    default:
        return NULL;
    }

    /* NOTREACHED  */
}
