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

/* Global error processing. */

apr_status_t
serf__global_error_callback(void *baton,
                            unsigned source,
                            apr_status_t status,
                            const char *message)
{
    return APR_SUCCESS;
}

static void *global_error_callback_baton = NULL;
static serf_error_cb_t global_error_callback = serf__global_error_callback;

void serf_global_error_callback_set(serf_error_cb_t callback, void *baton)
{
    global_error_callback_baton = baton;
    global_error_callback = callback;
}

/* The various process_*_error functions set the error source, then either
   call the appropriate error callback or, if that's not defined, send the
   message up the hierarchy until it's either handled by a registered
   callback or thrown away by default_global_error_callback().

   This way, the callers of serf__*_error() don't have to bother with
   the error source or check if their callbacks have been defined. */

static apr_status_t process_global_error(unsigned source,
                                         apr_status_t status,
                                         const char *message)
{
    if (0 == (source & SERF_ERROR_CB_MASK)) {
        source |= SERF_ERROR_CB_GLOBAL;
    }
    return global_error_callback(global_error_callback_baton,
                                 source, status, message);
}

/* Context error processing. */

static apr_status_t process_context_error(unsigned source,
                                          const serf_context_t* ctx,
                                          apr_status_t status,
                                          const char *message)
{
    if (0 == (source & SERF_ERROR_CB_MASK)) {
        source |= SERF_ERROR_CB_CONTEXT;
    }
    if (ctx->error_callback) {
        return ctx->error_callback(ctx->error_callback_baton,
                                   source, status, message);
    }
    return process_global_error(source, status, message);
}

apr_status_t serf__context_error(const serf_context_t* ctx,
                                 apr_status_t status,
                                 const char *message)
{
    return process_context_error(SERF_ERROR_CB_CONTEXT,
                                 ctx, status, message);
}

/* Connection error processing. */

static apr_status_t process_connection_error(unsigned source,
                                             const serf_connection_t *conn,
                                             apr_status_t status,
                                             const char *message)
{
    if (0 == (source & SERF_ERROR_CB_MASK)) {
        source |= SERF_ERROR_CB_OUTGOING;
    }
    if (conn->error_callback) {
        return conn->error_callback(conn->error_callback_baton,
                                    source, status, message);
    }
    return process_context_error(source, conn->ctx, status, message);
}

apr_status_t serf__connection_error(const serf_connection_t *conn,
                                    apr_status_t status,
                                    const char *message)
{
    return process_connection_error(SERF_ERROR_CB_OUTGOING,
                                    conn, status, message);
}

apr_status_t serf__request_error(const serf_request_t *req,
                                 apr_status_t status,
                                 const char *message)
{
    return process_connection_error(SERF_ERROR_CB_OUTGOING
                                    | SERF_ERROR_CB_REQUEST,
                                    req->conn, status, message);
}

apr_status_t serf__response_error(const serf_request_t *req,
                                  apr_status_t status,
                                  const char *message)
{
    return process_connection_error(SERF_ERROR_CB_OUTGOING
                                    | SERF_ERROR_CB_RESPONSE,
                                    req->conn, status, message);
}

/* Incoming error processing. */

static apr_status_t process_incoming_error(unsigned source,
                                           const serf_incoming_t *client,
                                           apr_status_t status,
                                           const char *message)
{
    if (0 == (source & SERF_ERROR_CB_MASK)) {
        source |= SERF_ERROR_CB_INCOMING;
    }
    if (client->error_callback) {
        return client->error_callback(client->error_callback_baton,
                                      source, status, message);
    }
    return process_context_error(source, client->ctx, status, message);
}

apr_status_t serf__incoming_error(const serf_incoming_t *client,
                                  apr_status_t status,
                                  const char *message)
{
    return process_incoming_error(SERF_ERROR_CB_INCOMING,
                                  client, status, message);
}

apr_status_t serf__incoming_request_error(const serf_incoming_request_t *req,
                                          apr_status_t status,
                                          const char *message)
{
    return process_incoming_error(SERF_ERROR_CB_INCOMING
                                  | SERF_ERROR_CB_REQUEST,
                                  req->incoming, status, message);
}

apr_status_t serf__incoming_response_error(const serf_incoming_request_t *req,
                                           apr_status_t status,
                                           const char *message)
{
    return process_incoming_error(SERF_ERROR_CB_INCOMING
                                  | SERF_ERROR_CB_RESPONSE,
                                  req->incoming, status, message);
}

/* Errors from the SSL context.

   Callers of the SSL functions can create an serf__ssl_error_ctx_t
   on the stack and pass it to the called function, which can then
   dispatch any errors it generates to the appropriate callback. */

apr_status_t serf__global_ssl_error(const void *baton,
                                    apr_status_t status,
                                    const char *message)
{
    /* Ignores the baton, since there's only one global error callback. */
    return process_global_error(SERF_ERROR_CB_SSL_CONTEXT
                                | SERF_ERROR_CB_GLOBAL,
                                status, message);
}

apr_status_t serf__context_ssl_error(const void *baton,
                                     apr_status_t status,
                                     const char *message)
{
    const serf_context_t *const ctx = baton;
    return process_context_error(SERF_ERROR_CB_SSL_CONTEXT
                                 | SERF_ERROR_CB_CONTEXT,
                                 ctx, status, message);
}


apr_status_t serf__connection_ssl_error(const void *baton,
                                        apr_status_t status,
                                        const char *message)
{
    const serf_connection_t *const conn = baton;
    return process_connection_error(SERF_ERROR_CB_SSL_CONTEXT
                                    | SERF_ERROR_CB_OUTGOING,
                                    conn, status, message);
}

apr_status_t serf__incoming_ssl_error(const void *baton,
                                      apr_status_t status,
                                      const char *message)
{
    const serf_incoming_t *const client = baton;
    return process_incoming_error(SERF_ERROR_CB_SSL_CONTEXT
                                  | SERF_ERROR_CB_INCOMING,
                                  client, status, message);
}
