/* 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 <assert.h>
#include <stddef.h>

#include <httpd.h>
#include <http_core.h>
#include <http_connection.h>
#include <http_log.h>

#include "h2_private.h"
#include "h2.h"
#include "h2_mplx.h"
#include "h2_stream.h"
#include "h2_bucket_eos.h"

typedef struct {
    apr_bucket_refcount refcount;
    h2_stream *stream;
} h2_bucket_eos;

static apr_status_t bucket_cleanup(void *data)
{
    h2_stream **pstream = data;

    if (*pstream) {
        /* If bucket_destroy is called after us, this prevents
         * bucket_destroy from trying to destroy the stream again. */
        *pstream = NULL;
    }
    return APR_SUCCESS;
}

static apr_status_t bucket_read(apr_bucket *b, const char **str,
                                apr_size_t *len, apr_read_type_e block)
{
    (void)b;
    (void)block;
    *str = NULL;
    *len = 0;
    return APR_SUCCESS;
}

apr_bucket *h2_bucket_eos_make(apr_bucket *b, h2_stream *stream)
{
    h2_bucket_eos *h;

    h = apr_bucket_alloc(sizeof(*h), b->list);
    h->stream = stream;

    b = apr_bucket_shared_make(b, h, 0, 0);
    b->type = &h2_bucket_type_eos;
    
    return b;
}

apr_bucket *h2_bucket_eos_create(apr_bucket_alloc_t *list,
                                 h2_stream *stream)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    b = h2_bucket_eos_make(b, stream);
    if (stream) {
        h2_bucket_eos *h = b->data;
        apr_pool_pre_cleanup_register(stream->pool, &h->stream, bucket_cleanup);
    }
    return b;
}

static void bucket_destroy(void *data)
{
    h2_bucket_eos *h = data;

    if (apr_bucket_shared_destroy(h)) {
        h2_stream *stream = h->stream;
        if (stream && stream->pool) {
            apr_pool_cleanup_kill(stream->pool, &h->stream, bucket_cleanup);
        }
        apr_bucket_free(h);
        if (stream) {
            h2_stream_eos_destroy(stream);
        }
    }
}

const apr_bucket_type_t h2_bucket_type_eos = {
    "H2EOS", 5, APR_BUCKET_METADATA,
    bucket_destroy,
    bucket_read,
    apr_bucket_setaside_noop,
    apr_bucket_split_notimpl,
    apr_bucket_shared_copy
};

