/* 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_optional.h>
#include <apr_optional_hooks.h>
#include <apr_strings.h>
#include <apr_time.h>
#include <apr_want.h>

#include <httpd.h>
#include <http_protocol.h>
#include <http_request.h>
#include <http_log.h>
#include <mpm_common.h>

#include "mod_http2.h"

#include <nghttp2/nghttp2.h>
#include "h2_stream.h"
#include "h2_c1.h"
#include "h2_c2.h"
#include "h2_session.h"
#include "h2_config.h"
#include "h2_conn_ctx.h"
#include "h2_protocol.h"
#include "h2_mplx.h"
#include "h2_push.h"
#include "h2_request.h"
#include "h2_switch.h"
#include "h2_version.h"
#include "h2_bucket_beam.h"


static void h2_hooks(apr_pool_t *pool);

AP_DECLARE_MODULE(http2) = {
    STANDARD20_MODULE_STUFF,
    h2_config_create_dir, /* func to create per dir config */
    h2_config_merge_dir,  /* func to merge per dir config */
    h2_config_create_svr, /* func to create per server config */
    h2_config_merge_svr,  /* func to merge per server config */
    h2_cmds,              /* command handlers */
    h2_hooks,
#if defined(AP_MODULE_FLAG_NONE)
    AP_MODULE_FLAG_ALWAYS_MERGE
#endif
};

static int h2_h2_fixups(request_rec *r);

typedef struct {
    unsigned int change_prio : 1;
    unsigned int sha256 : 1;
    unsigned int inv_headers : 1;
    unsigned int dyn_windows : 1;
} features;

static features myfeats;
static int mpm_warned;

/* The module initialization. Called once as apache hook, before any multi
 * processing (threaded or not) happens. It is typically at least called twice, 
 * see
 * http://wiki.apache.org/httpd/ModuleLife
 * Since the first run is just a "practise" run, we want to initialize for real
 * only on the second try. This defeats the purpose of the first dry run a bit, 
 * since apache wants to verify that a new configuration actually will work. 
 * So if we have trouble with the configuration, this will only be detected 
 * when the server has already switched.
 * On the other hand, when we initialize lib nghttp2, all possible crazy things 
 * might happen and this might even eat threads. So, better init on the real 
 * invocation, for now at least.
 */
static int h2_post_config(apr_pool_t *p, apr_pool_t *plog,
                          apr_pool_t *ptemp, server_rec *s)
{
    void *data = NULL;
    const char *mod_h2_init_key = "mod_http2_init_counter";
    nghttp2_info *ngh2;
    apr_status_t status;
    
    (void)plog;(void)ptemp;
#ifdef H2_NG2_CHANGE_PRIO
    myfeats.change_prio = 1;
#endif
#ifdef H2_OPENSSL
    myfeats.sha256 = 1;
#endif
#ifdef H2_NG2_INVALID_HEADER_CB
    myfeats.inv_headers = 1;
#endif
#ifdef H2_NG2_LOCAL_WIN_SIZE
    myfeats.dyn_windows = 1;
#endif
    
    apr_pool_userdata_get(&data, mod_h2_init_key, s->process->pool);
    if ( data == NULL ) {
        ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03089)
                     "initializing post config dry run");
        apr_pool_userdata_set((const void *)1, mod_h2_init_key,
                              apr_pool_cleanup_null, s->process->pool);
        return APR_SUCCESS;
    }
    
    ngh2 = nghttp2_version(0);
    ap_log_error( APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(03090)
                 "mod_http2 (v%s, feats=%s%s%s%s, nghttp2 %s), initializing...",
                 MOD_HTTP2_VERSION, 
                 myfeats.change_prio? "CHPRIO"  : "", 
                 myfeats.sha256?      "+SHA256" : "",
                 myfeats.inv_headers? "+INVHD"  : "",
                 myfeats.dyn_windows? "+DWINS"  : "",
                 ngh2?                ngh2->version_str : "unknown");
    
    if (!h2_mpm_supported() && !mpm_warned) {
        mpm_warned = 1;
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10034)
                     "The mpm module (%s) is not supported by mod_http2. The mpm determines "
                     "how things are processed in your server. HTTP/2 has more demands in "
                     "this regard and the currently selected mpm will just not do. "
                     "This is an advisory warning. Your server will continue to work, but "
                     "the HTTP/2 protocol will be inactive.", 
                     h2_conn_mpm_name());
    }
    
    status = h2_protocol_init(p, s);
    if (status == APR_SUCCESS) {
        status = h2_switch_init(p, s);
    }

    return status;
}

static char *http2_var_lookup(apr_pool_t *, server_rec *,
                         conn_rec *, request_rec *, char *name);
static int http2_is_h2(conn_rec *);

static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
{
    apr_time_t tdummy;

    h2_get_workers_config(s, minw, maxw, &tdummy);
}

/* Runs once per created child process. Perform any process 
 * related initionalization here.
 */
static void h2_child_init(apr_pool_t *pchild, server_rec *s)
{
    apr_status_t rv;

    /* Set up our connection processing */
    rv = h2_c1_child_init(pchild, s);
    if (APR_SUCCESS == rv) {
        rv = h2_c2_child_init(pchild, s);
    }
    if (APR_SUCCESS != rv) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                     APLOGNO(02949) "initializing connection handling");
    }
}

/* Install this module into the apache2 infrastructure.
 */
static void h2_hooks(apr_pool_t *pool)
{
    static const char *const mod_ssl[] = { "mod_ssl.c", NULL};
    
    APR_REGISTER_OPTIONAL_FN(http2_is_h2);
    APR_REGISTER_OPTIONAL_FN(http2_var_lookup);
    APR_REGISTER_OPTIONAL_FN(http2_get_num_workers);

    ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
    
    /* Run once after configuration is set, but before mpm children initialize.
     */
    ap_hook_post_config(h2_post_config, mod_ssl, NULL, APR_HOOK_MIDDLE);
    
    /* Run once after a child process has been created.
     */
    ap_hook_child_init(h2_child_init, NULL, NULL, APR_HOOK_MIDDLE);
#if AP_MODULE_MAGIC_AT_LEAST(20120211, 110)
    ap_hook_child_stopping(h2_c1_child_stopping, NULL, NULL, APR_HOOK_MIDDLE);
#endif

    h2_c1_register_hooks();
    h2_switch_register_hooks();
    h2_c2_register_hooks();

    /* Setup subprocess env for certain variables
     */
    ap_hook_fixups(h2_h2_fixups, NULL,NULL, APR_HOOK_MIDDLE);
}

static const char *val_HTTP2(apr_pool_t *p, server_rec *s,
                             conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
{
    return ctx? "on" : "off";
}

static const char *val_H2_PUSH(apr_pool_t *p, server_rec *s,
                               conn_rec *c, request_rec *r,
                               h2_conn_ctx_t *conn_ctx)
{
    if (conn_ctx) {
        if (r) {
            if (conn_ctx->stream_id) {
                const h2_stream *stream = h2_mplx_c2_stream_get(conn_ctx->mplx, conn_ctx->stream_id);
                if (stream && stream->push_policy != H2_PUSH_NONE) {
                    return "on";
                }
            }
        }
        else if (c && h2_session_push_enabled(conn_ctx->session)) {
            return "on";
        }
    }
    else if (s) {
        if (h2_config_geti(r, s, H2_CONF_PUSH)) {
            return "on";
        }
    }
    return "off";
}

static const char *val_H2_PUSHED(apr_pool_t *p, server_rec *s,
                                 conn_rec *c, request_rec *r,
                                 h2_conn_ctx_t *conn_ctx)
{
    if (conn_ctx) {
        if (conn_ctx->stream_id && !H2_STREAM_CLIENT_INITIATED(conn_ctx->stream_id)) {
            return "PUSHED";
        }
    }
    return "";
}

static const char *val_H2_PUSHED_ON(apr_pool_t *p, server_rec *s,
                                    conn_rec *c, request_rec *r,
                                    h2_conn_ctx_t *conn_ctx)
{
    if (conn_ctx) {
        if (conn_ctx->stream_id && !H2_STREAM_CLIENT_INITIATED(conn_ctx->stream_id)) {
            const h2_stream *stream = h2_mplx_c2_stream_get(conn_ctx->mplx, conn_ctx->stream_id);
            if (stream) {
                return apr_itoa(p, stream->initiated_on);
            }
        }
    }
    return "";
}

static const char *val_H2_STREAM_TAG(apr_pool_t *p, server_rec *s,
                                     conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
{
    if (c) {
        h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(c);
        if (conn_ctx) {
            return conn_ctx->stream_id == 0? conn_ctx->id
               : apr_psprintf(p, "%s-%d", conn_ctx->id, conn_ctx->stream_id);
        }
    }
    return "";
}

static const char *val_H2_STREAM_ID(apr_pool_t *p, server_rec *s,
                                    conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
{
    const char *cp = val_H2_STREAM_TAG(p, s, c, r, ctx);
    if (cp && (cp = ap_strrchr_c(cp, '-'))) {
        return ++cp;
    }
    return NULL;
}

typedef const char *h2_var_lookup(apr_pool_t *p, server_rec *s,
                                  conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx);
typedef struct h2_var_def {
    const char *name;
    h2_var_lookup *lookup;
    unsigned int  subprocess : 1;    /* should be set in r->subprocess_env */
} h2_var_def;

static h2_var_def H2_VARS[] = {
    { "HTTP2",               val_HTTP2,  1 },
    { "H2PUSH",              val_H2_PUSH, 1 },
    { "H2_PUSH",             val_H2_PUSH, 1 },
    { "H2_PUSHED",           val_H2_PUSHED, 1 },
    { "H2_PUSHED_ON",        val_H2_PUSHED_ON, 1 },
    { "H2_STREAM_ID",        val_H2_STREAM_ID, 1 },
    { "H2_STREAM_TAG",       val_H2_STREAM_TAG, 1 },
};

#ifndef H2_ALEN
#define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))
#endif


static int http2_is_h2(conn_rec *c)
{
    return h2_conn_ctx_get(c->master? c->master : c) != NULL;
}

static char *http2_var_lookup(apr_pool_t *p, server_rec *s,
                              conn_rec *c, request_rec *r, char *name)
{
    unsigned int i;
    /* If the # of vars grow, we need to put definitions in a hash */
    for (i = 0; i < H2_ALEN(H2_VARS); ++i) {
        h2_var_def *vdef = &H2_VARS[i];
        if (!strcmp(vdef->name, name)) {
            h2_conn_ctx_t *ctx = (r? h2_conn_ctx_get(c) :
                           h2_conn_ctx_get(c->master? c->master : c));
            return (char *)vdef->lookup(p, s, c, r, ctx);
        }
    }
    return (char*)"";
}

static int h2_h2_fixups(request_rec *r)
{
    if (r->connection->master) {
        h2_conn_ctx_t *ctx = h2_conn_ctx_get(r->connection);
        unsigned int i;

        for (i = 0; ctx && i < H2_ALEN(H2_VARS); ++i) {
            h2_var_def *vdef = &H2_VARS[i];
            if (vdef->subprocess) {
                apr_table_setn(r->subprocess_env, vdef->name, 
                               vdef->lookup(r->pool, r->server, r->connection, 
                                            r, ctx));
            }
        }
    }
    return DECLINED;
}
