/*
 * 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.
 */

/* $Rev$ $Date$ */

#ifndef tuscany_httpd_hpp
#define tuscany_httpd_hpp

/**
 * HTTPD module implementation functions.
 */

#include "apr_strings.h"
#include "apr_fnmatch.h"
#include "apr_lib.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"

#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_request.h"
#include "http_protocol.h"
#include "http_log.h"
#include "http_main.h"
#include "util_script.h"
#include "util_md5.h"
#include "http_config.h"
#include "ap_mpm.h"
#include "mod_core.h"

#include "string.hpp"
#include "stream.hpp"
#include "list.hpp"
#include "value.hpp"


namespace tuscany {
namespace httpd {

/**
 * Returns a server-scoped module configuration.
 */
template<typename C> void* makeServerConf(apr_pool_t *p, server_rec *s) {
    return new (gc_new<C>(p)) C(s);
}

template<typename C> const C& serverConf(const request_rec* r, const module* mod) {
    return *(C*)ap_get_module_config(r->server->module_config, mod);
}

template<typename C> C& serverConf(const server_rec* s, const module* mod) {
    return *(C*)ap_get_module_config(s->module_config, mod);
}

template<typename C> C& serverConf(const cmd_parms *cmd, const module* mod) {
    return *(C*)ap_get_module_config(cmd->server->module_config, mod);
}


/**
 * Return the content type of a request.
 */
const char* optional(const char* s) {
    if (s == NULL)
        return "";
    return s;
}

const string contentType(const request_rec* r) {
    return optional(apr_table_get(r->headers_in, "Content-Type"));
}

#ifdef WANT_MAINTAINER_MODE

/**
 * Debug log.
 */
int debugHeader(unused void* r, const char* key, const char* value) {
    cerr << "  header key: " << key << ", value: " << value << endl;
    return 1;
}

const bool debugRequest(request_rec* r, const string& msg) {
    cerr << msg << ":" << endl;
    cerr << "  protocol: " << optional(r->protocol) << endl;
    cerr << "  method: " << optional(r->method) << endl;
    cerr << "  method number: " << r->method_number << endl;
    cerr << "  content type: " << contentType(r) << endl;
    cerr << "  content encoding: " << optional(r->content_encoding) << endl;
    apr_table_do(debugHeader, r, r->headers_in, NULL);
    cerr << "  unparsed uri: " << optional(r->unparsed_uri) << endl;
    cerr << "  uri: " << optional(r->uri) << endl;
    cerr << "  path info: " << optional(r->path_info) << endl;
    cerr << "  filename: " << optional(r->filename) << endl;
    cerr << "  uri tokens: " << pathTokens(r->uri) << endl;
    cerr << "  args: " << optional(r->args) << endl;
    return true;
}

#define httpdDebugRequest(r, msg) httpd::debugRequest(r, msg)

#else

#define httpdDebugRequest(r, msg)

#endif

/**
 * Return the remaining part of a uri after the given path (aka the path info.)
 */
const list<value> pathInfo(const list<value>& uri, const list<value>& path) {
    if (isNil(path))
        return uri;
    return pathInfo(cdr(uri), cdr(path));
}

/**
 * Returns a list of key value pairs from the args in a query string.
 */
const list<value> queryArg(const string& s) {
    const list<string> t = tokenize("=", s);
    return mklist<value>(c_str(car(t)), cadr(t));
}

const list<list<value> > queryArgs(const request_rec* r) {
    const char* a = r->args;
    if (a == NULL)
        return list<list<value> >();
    return map<string, list<value>>(queryArg, tokenize("&", a));
}

/**
 * Returns a list of param values other than the id and method args from a list
 * of key value pairs.
 */
const list<value> queryParams(const list<list<value> >& a) {
    if (isNil(a))
        return list<value>();
    const list<value> p = car(a);
    if (car(p) == value("id") || car(p) == value("method"))
        return queryParams(cdr(a));
    return cons(cadr(p), queryParams(cdr(a)));
}

/**
 * Converts the args received in a POST to a list of key value pairs.
 */
const list<list<value> > postArgs(const list<value>& a) {
    if (isNil(a))
        return list<list<value> >();
    const list<value> l = car(a);
    return cons(l, postArgs(cdr(a)));
}

/**
 * Setup the HTTP read policy.
 */
const int setupReadPolicy(request_rec* r) {
    const int rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
    if(rc != OK)
        return rc;
    ap_should_client_block(r);
    if(r->read_chunked == true && r->remaining == 0)
        r->chunked = true;
    //apr_table_setn(r->headers_out, "Connection", "close");
    return OK;
}

/**
 * Read the content of a POST or PUT.
 */
const list<string> read(request_rec* r) {
    char b[1024];
    const int n = ap_get_client_block(r, b, sizeof(b));
    if (n <= 0)
        return list<string>();
    return cons(string(b, n), read(r));
}

/**
 * Convert a URI represented as a list to an absolute URL.
 */
const char* url(const list<value>& v, request_rec* r) {
    const string u = string(r->uri) + path(v);
    return ap_construct_url(r->pool, c_str(u), r);
}

/**
 * Write an HTTP result.
 */
const failable<int> writeResult(const failable<list<string> >& ls, const string& ct, request_rec* r) {
    if (!hasContent(ls))
        return mkfailure<int>(reason(ls));
    ostringstream os;
    write(content(ls), os);
    const string ob(str(os));
    debug(ob, "httpd::result");

    const string etag(ap_md5(r->pool, (const unsigned char*)c_str(ob)));
    const char* match = apr_table_get(r->headers_in, "If-None-Match");
    apr_table_setn(r->headers_out, "ETag", apr_pstrdup(r->pool, c_str(etag)));
    if (match != NULL  && etag == match) {
        r->status = HTTP_NOT_MODIFIED;
        return OK;
    }
    ap_set_content_type(r, apr_pstrdup(r->pool, c_str(ct)));
    ap_rputs(c_str(ob), r);
    return OK;
}

/**
 * Report request execution status.
 */
const int reportStatus(const failable<int>& rc) {
    if (!hasContent(rc))
        return HTTP_INTERNAL_SERVER_ERROR;
    return content(rc);
}

/**
 * Construct a redirect URI.
 */
const string redirectURI(const string& file, const string& pi) {
    return file + pi;
}

const string redirectURI(const string& file, const string& pi, const string& args) {
    return file + pi + "?" + args;
}

/**
 * Convert a value to an HTTPD request struc
 */
request_rec* request(const value& v) {
    return (request_rec*)(long)(double)v;
}

/**
 * Convert an HTTPD request struct to a value
 */
const value requestValue(request_rec* r) {
    return value((double)(long)r);
}

/**
 * Update filters in an HTTPD redirect request.
 * Similar to httpd/modules/http/http_request.c::update_r_in_filters.
 */
const bool redirectFilters(ap_filter_t* f, request_rec* from, request_rec* to) {
    if (f == NULL)
        return true;
    if (f->r == from)
        f->r = to;
    return redirectFilters(f->next, from, to);
}

/**
 * Create an HTTPD redirect request.
 * Similar to httpd/modules/http/http_request.c::internal_internal_redirect.
 */
extern "C" {
    AP_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p);
}

const failable<request_rec*, int> internalRedirectRequest(const string& nr_uri, request_rec* r) {
    if (ap_is_recursion_limit_exceeded(r))
        return mkfailure<request_rec*, int>(HTTP_INTERNAL_SERVER_ERROR);

    // Create a new request
    request_rec* nr = (request_rec*)apr_pcalloc(r->pool, sizeof(request_rec));
    nr->connection = r->connection;
    nr->server = r->server;
    nr->pool = r->pool;
    nr->method = r->method;
    nr->method_number = r->method_number;
    nr->allowed_methods = ap_make_method_list(nr->pool, 2);
    ap_parse_uri(nr, apr_pstrdup(nr->pool, c_str(nr_uri)));
    nr->request_config = ap_create_request_config(r->pool);
    nr->per_dir_config = r->server->lookup_defaults;
    nr->prev = r;
    r->next   = nr;

    // Run create request hook
    ap_run_create_request(nr);

    // Inherit protocol info from the original request
    nr->the_request = r->the_request;
    nr->allowed = r->allowed;
    nr->status = r->status;
    nr->assbackwards = r->assbackwards;
    nr->header_only = r->header_only;
    nr->protocol = r->protocol;
    nr->proto_num = r->proto_num;
    nr->hostname = r->hostname;
    nr->request_time = r->request_time;
    nr->main = r->main;
    nr->headers_in = r->headers_in;
    nr->headers_out = apr_table_make(r->pool, 12);
    nr->err_headers_out = r->err_headers_out;
    nr->subprocess_env = r->subprocess_env;
    nr->notes = apr_table_make(r->pool, 5);
    nr->allowed_methods = ap_make_method_list(nr->pool, 2);
    nr->htaccess = r->htaccess;
    nr->no_cache = r->no_cache;
    nr->expecting_100 = r->expecting_100;
    nr->no_local_copy = r->no_local_copy;
    nr->read_length = r->read_length;
    nr->vlist_validator = r->vlist_validator;

    // Setup input and output filters
    nr->proto_output_filters  = r->proto_output_filters;
    nr->proto_input_filters   = r->proto_input_filters;
    nr->output_filters  = nr->proto_output_filters;
    nr->input_filters   = nr->proto_input_filters;
    if (nr->main)
        ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, nr, nr->connection);
    redirectFilters(nr->input_filters, r, nr);
    redirectFilters(nr->output_filters, r, nr);
    const int rrc = ap_run_post_read_request(nr);
    if (rrc != OK && rrc != DECLINED)
        return mkfailure<request_rec*, int>(rrc);

    return nr;
}

/**
 * Process an HTTPD internal redirect request.
 * Similar to httpd/modules/http/http_request.c::ap_internal_redirect.
 */
extern "C" {
    AP_DECLARE(int) ap_invoke_handler(request_rec *r);
}

const int internalRedirect(request_rec* nr) {
    int status = ap_run_quick_handler(nr, 0);
    if (status == DECLINED) {
        status = ap_process_request_internal(nr);
        if (status == OK)
            status = ap_invoke_handler(nr);
    }
    if (status != OK) {
        nr->status = status;
        return OK;
    }
    ap_finalize_request_protocol(nr);
    return OK;
}

/**
 * Create and process an HTTPD redirect request.
 */
const int internalRedirect(const string& uri, request_rec* r) {
    const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r);
    if (!hasContent(nr))
        return reason(nr);
    return httpd::internalRedirect(content(nr));
}

/**
 * Put a value in the process user data.
 */
const bool putUserData(const string& k, const void* v, const server_rec* s) {
    apr_pool_userdata_set((const void *)v, c_str(k), apr_pool_cleanup_null, s->process->pool);
    return true;
}

/**
 * Return a user data value.
 */
const void* userData(const string& k, const server_rec* s) {
    void* v = NULL;
    apr_pool_userdata_get(&v, c_str(k), s->process->pool);
    return v;
}

}
}

#endif /* tuscany_httpd_hpp */
