/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"

#include <stdlib.h>
#if APR_HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#include "httpd.h"
#include "ap_buckets.h"

static apr_array_header_t *bucket_types;

static apr_status_t ap_brigade_cleanup(void *data)
{
    ap_bucket_brigade *b = data;
    ap_bucket *e;

    /*
     * Bah! We can't use AP_RING_FOREACH here because this bucket has
     * gone away when we dig inside it to get the next one.
     */
    while (!AP_BRIGADE_EMPTY(b)) {
	e = AP_BRIGADE_FIRST(b);
	AP_BUCKET_REMOVE(e);
	ap_bucket_destroy(e);
    }
    /*
     * We don't need to free(bb) because it's allocated from a pool.
     */
    return APR_SUCCESS;
}
AP_DECLARE(apr_status_t) ap_brigade_destroy(ap_bucket_brigade *b)
{
    apr_kill_cleanup(b->p, b, ap_brigade_cleanup);
    return ap_brigade_cleanup(b);
}

AP_DECLARE(ap_bucket_brigade *) ap_brigade_create(apr_pool_t *p)
{
    ap_bucket_brigade *b;

    b = apr_palloc(p, sizeof(*b));
    b->p = p;
    AP_RING_INIT(&b->list, ap_bucket, link);

    apr_register_cleanup(b->p, b, ap_brigade_cleanup, ap_brigade_cleanup);
    return b;
}

AP_DECLARE(ap_bucket_brigade *) ap_brigade_split(ap_bucket_brigade *b,
						 ap_bucket *e)
{
    ap_bucket_brigade *a;
    ap_bucket *f;

    a = ap_brigade_create(b->p);
    /* Return an empty brigade if there is nothing left in 
     * the first brigade to split off 
     */
    if (e != AP_BRIGADE_SENTINEL(b)) {
        f = AP_RING_LAST(&b->list);
        AP_RING_UNSPLICE(e, f, link);
        AP_RING_SPLICE_HEAD(&a->list, e, f, ap_bucket, link);
    }
    return a;
}

AP_DECLARE(int) ap_brigade_to_iovec(ap_bucket_brigade *b, 
				    struct iovec *vec, int nvec)
{
    ap_bucket *e;
    struct iovec *orig;
    apr_size_t iov_len;

    orig = vec;
    AP_BRIGADE_FOREACH(e, b) {
	if (nvec-- == 0)
            break;
	ap_bucket_read(e, (const char **)&vec->iov_base, &iov_len, AP_NONBLOCK_READ);
        vec->iov_len = iov_len; /* set indirectly in case size differs */
	++vec;
    }
    return vec - orig;
}

AP_DECLARE(int) ap_brigade_vputstrs(ap_bucket_brigade *b, va_list va)
{
    ap_bucket *r;
    const char *x;
    int j, k;
    apr_size_t i;

    for (k = 0;;) {
        x = va_arg(va, const char *);
        if (x == NULL)
            break;
        j = strlen(x);
       
	/* XXX: copy or not? let the caller decide? */
        r = ap_bucket_create_heap(x, j, 1, &i);
        if (i != j) {
            /* Do we need better error reporting?  */
            return -1;
        }
        k += i;

        AP_BRIGADE_INSERT_TAIL(b, r);
    }

    return k;
}

AP_DECLARE_NONSTD(int) ap_brigade_putstrs(ap_bucket_brigade *b, ...)
{
    va_list va;
    int written;

    va_start(va, b);
    written = ap_brigade_vputstrs(b, va);
    va_end(va);
    return written;
}

AP_DECLARE_NONSTD(int) ap_brigade_printf(ap_bucket_brigade *b, const char *fmt, ...)
{
    va_list ap;
    int res;

    va_start(ap, fmt);
    res = ap_brigade_vprintf(b, fmt, ap);
    va_end(ap);
    return res;
}

AP_DECLARE(int) ap_brigade_vprintf(ap_bucket_brigade *b, const char *fmt, va_list va)
{
    /* XXX:  This needs to be replaced with a function to printf
     * directly into a bucket.  I'm being lazy right now.  RBB
     */
    char buf[4096];
    ap_bucket *r;
    int res;

    res = apr_vsnprintf(buf, 4096, fmt, va);

    r = ap_bucket_create_heap(buf, strlen(buf), 1, NULL);
    AP_BRIGADE_INSERT_TAIL(b, r);

    return res;
}

void ap_init_bucket_types(apr_pool_t *p)
{
    bucket_types = apr_make_array(p, 8, sizeof(ap_bucket_type));

    ap_insert_bucket_type(&ap_eos_type);
    ap_insert_bucket_type(&ap_file_type);
    ap_insert_bucket_type(&ap_heap_type);
#ifdef AP_USE_MMAP_FILES
    ap_insert_bucket_type(&ap_mmap_type);
#endif
    ap_insert_bucket_type(&ap_pipe_type);
    ap_insert_bucket_type(&ap_immortal_type);
    ap_insert_bucket_type(&ap_transient_type);
    ap_insert_bucket_type(&ap_socket_type);
}

int ap_insert_bucket_type(const ap_bucket_type *type)
{
    const ap_bucket_type **newone;

    newone = (const ap_bucket_type **)apr_push_array(bucket_types);
    newone = &type;

    return bucket_types->nelts - 1;
}

AP_DECLARE_NONSTD(apr_status_t) ap_bucket_setaside_notimpl(ap_bucket *data)
{
    return APR_ENOTIMPL;
}

AP_DECLARE_NONSTD(apr_status_t) ap_bucket_split_notimpl(ap_bucket *data, apr_off_t point)
{
    return APR_ENOTIMPL;
}

AP_DECLARE_NONSTD(void) ap_bucket_destroy_notimpl(void *data)
{
    return;
}
