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

typedef struct file_context_t {
    apr_file_t *file;

    serf_databuf_t databuf;
    apr_uint64_t remaining;
} file_context_t;


static apr_status_t file_reader(void *baton, apr_size_t bufsize,
                                char *buf, apr_size_t *len)
{
    file_context_t *ctx = baton;

    *len = bufsize;
    return apr_file_read(ctx->file, buf, len);
}

serf_bucket_t *serf_bucket_file_create(
    apr_file_t *file,
    serf_bucket_alloc_t *allocator)
{
    apr_status_t status;
    file_context_t *ctx;
    apr_finfo_t finfo;

    status = apr_file_info_get(&finfo, APR_FINFO_SIZE, file);

#if APR_HAS_MMAP
    /* See if we'd be better off mmap'ing this file instead.
     *
     * Note that there is a failure case here that we purposely fall through:
     * if a file is buffered, apr_mmap will reject it.  However, on older
     * versions of APR, we have no way of knowing this - but apr_mmap_create
     * will check for this and return APR_EBADF.
     */
    if (status == APR_SUCCESS && APR_MMAP_CANDIDATE(finfo.size)) {
        apr_mmap_t *file_mmap;
        status = apr_mmap_create(&file_mmap, file, 0, finfo.size,
                                 APR_MMAP_READ,
                                 serf_bucket_allocator_get_pool(allocator));

        if (status == APR_SUCCESS) {
            return serf_bucket_mmap_create(file_mmap, allocator);
        }
    }
#endif

    /* Oh, well. */
    ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
    ctx->file = file;

    serf_databuf_init(&ctx->databuf);
    ctx->databuf.read = file_reader;
    ctx->databuf.read_baton = ctx;

    if (status == APR_SUCCESS) {
        ctx->remaining = finfo.size;
    }
    else {
        ctx->remaining = SERF_LENGTH_UNKNOWN;
    }

    return serf_bucket_create(&serf_bucket_type_file, allocator, ctx);
}

static apr_status_t serf_file_read(serf_bucket_t *bucket,
                                   apr_size_t requested,
                                   const char **data, apr_size_t *len)
{
    file_context_t *ctx = bucket->data;
    apr_status_t status;

    status = serf_databuf_read(&ctx->databuf, requested, data, len);

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

    /* Update remaining length if known. */
    if (ctx->remaining != SERF_LENGTH_UNKNOWN) {
        ctx->remaining -= *len;
    }

    return status;
}

static apr_status_t serf_file_readline(serf_bucket_t *bucket,
                                       int acceptable, int *found,
                                       const char **data, apr_size_t *len)
{
    file_context_t *ctx = bucket->data;
    apr_status_t status;

    status = serf_databuf_readline(&ctx->databuf, acceptable, found, data, len);

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

    /* Update remaining length if known. */
    if (ctx->remaining != SERF_LENGTH_UNKNOWN) {
        ctx->remaining -= *len;
    }

    return status;

}

static apr_status_t serf_file_peek(serf_bucket_t *bucket,
                                   const char **data,
                                   apr_size_t *len)
{
    file_context_t *ctx = bucket->data;

    return serf_databuf_peek(&ctx->databuf, data, len);
}

static apr_uint64_t serf_file_get_remaining(serf_bucket_t *bucket)
{
    file_context_t *ctx = bucket->data;
    return ctx->remaining;
}

const serf_bucket_type_t serf_bucket_type_file = {
    "FILE",
    serf_file_read,
    serf_file_readline,
    serf_default_read_iovec,
    serf_default_read_for_sendfile,
    serf_buckets_are_v2,
    serf_file_peek,
    serf_default_destroy_and_data,
    serf_default_read_bucket,
    serf_file_get_remaining,
    serf_default_ignore_config,
};
