/* ====================================================================
 *    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 <stdlib.h>

#include <apr.h>
#include <apr_uri.h>
#include <apr_signal.h>
#include <apr_strings.h>
#include <apr_atomic.h>
#include <apr_base64.h>
#include <apr_getopt.h>
#include <apr_version.h>

#include "serf.h"

typedef struct app_ctx_t {
    int foo;
    apr_pool_t *pool;
} app_ctx_t;

typedef struct listener_ctx_t {
    app_ctx_t *app;
    const char *proto;

} listener_ctx_t;

typedef struct client_ctx_t {
    listener_ctx_t *listener;
    apr_pool_t *pool;
    serf_bucket_alloc_t *alloc;
} client_ctx_t;

typedef struct request_ctx_t {
    client_ctx_t *client;
    apr_pool_t *pool;
    serf_bucket_t *headers;
    const char *method;
    const char *path;
    int http_version;
} request_ctx_t;

static int pool_abort_func(int retcode)
{
    fprintf(stderr, "Out of memory\n");
    abort();
    return 0;
}

/* A flag to see if we've been cancelled by the client or not. */
static volatile sig_atomic_t cancelled = FALSE;

/* A signal handler to support cancellation. */
static void
signal_handler(int signum)
{
    apr_signal(signum, SIG_IGN);
    cancelled = TRUE;
}


static apr_status_t client_setup(apr_socket_t *skt,
                                 serf_bucket_t **read_bkt,
                                 serf_bucket_t **write_bkt,
                                 void *setup_baton,
                                 apr_pool_t *pool)
{
    client_ctx_t *cctx = setup_baton;
    if (cctx->alloc == NULL)
        cctx->alloc = serf_bucket_allocator_create(cctx->pool, NULL, NULL);

    *read_bkt = serf_bucket_socket_create(skt, cctx->alloc);
    return APR_SUCCESS;
}

static apr_status_t client_closed(serf_incoming_t *incoming,
                                  void *closed_baton,
                                  apr_status_t why,
                                  apr_pool_t *pool)
{
    client_ctx_t *cctx = closed_baton;
    apr_pool_destroy(cctx->pool);
    return APR_SUCCESS;
}

static apr_status_t request_handler(serf_incoming_request_t *req,
                                    serf_bucket_t *request,
                                    void *handler_baton,
                                    apr_pool_t *pool)
{
    request_ctx_t *rctx = handler_baton;
    apr_status_t status;

    if (!rctx->method) {
        status = serf_bucket_incoming_request_read(&rctx->headers,
                                                   &rctx->method,
                                                   &rctx->path,
                                                   &rctx->http_version,
                                                   request);
        if (status) {
            rctx->method = NULL;
            return status;
        }
    }

    status = serf_bucket_incoming_request_wait_for_headers(request);
    if (status)
        return status;

    status = serf_incoming_response_create(req);
    if (status)
        return status;

    do
    {
        const char *data;
        apr_size_t len;

        status = serf_bucket_read(request, SERF_READ_ALL_AVAIL, &data, &len);
    } while (status == APR_SUCCESS);

    return status;
}

static apr_status_t request_generate_response(serf_bucket_t **resp_bkt,
                                              serf_incoming_request_t *req,
                                              void *setup_baton,
                                              serf_bucket_alloc_t *alloc,
                                              apr_pool_t *pool)
{
    request_ctx_t *rctx = setup_baton;
    serf_bucket_t *agg = serf_bucket_aggregate_create(alloc);
    serf_bucket_t *body;
    serf_bucket_t *tmp;
#define CRLF "\r\n"

    tmp = SERF_BUCKET_SIMPLE_STRING("HTTP/1.1 200 BOE" CRLF, alloc);
    serf_bucket_aggregate_append(agg, tmp);

    tmp = SERF_BUCKET_SIMPLE_STRING("Content-Type: text/plain" CRLF, alloc);
    serf_bucket_aggregate_append(agg, tmp);

    tmp = SERF_BUCKET_SIMPLE_STRING(CRLF, alloc);
    serf_bucket_aggregate_append(agg, tmp);

    body = serf_bucket_aggregate_create(alloc);

    if (rctx->method)
    {
        tmp = SERF_BUCKET_SIMPLE_STRING("Method: ", alloc);
        serf_bucket_aggregate_append(body, tmp);

        tmp = serf_bucket_simple_copy_create(rctx->method, strlen(rctx->method), alloc);
        serf_bucket_aggregate_append(body, tmp);

        tmp = SERF_BUCKET_SIMPLE_STRING(CRLF "Path: ", alloc);
        serf_bucket_aggregate_append(body, tmp);

        tmp = serf_bucket_simple_copy_create(rctx->path, strlen(rctx->path), alloc);
        serf_bucket_aggregate_append(body, tmp);

        tmp = SERF_BUCKET_SIMPLE_STRING(CRLF, alloc);
        serf_bucket_aggregate_append(body, tmp);
    }

    tmp = SERF_BUCKET_SIMPLE_STRING(CRLF, alloc);
    serf_bucket_aggregate_append(body, tmp);

    tmp = body;
    serf_bucket_aggregate_append(agg, tmp);

    tmp = SERF_BUCKET_SIMPLE_STRING(CRLF, alloc);
    serf_bucket_aggregate_append(agg, tmp);

    *resp_bkt = agg;
    return APR_SUCCESS;
}

static apr_status_t client_request_acceptor(serf_bucket_t **req_bkt,
                                            serf_bucket_t *stream,
                                            serf_incoming_request_t *req,
                                            void *request_baton,
                                            serf_incoming_request_handler_t *handler,
                                            void **handler_baton,
                                            serf_incoming_response_setup_t *response_setup,
                                            void **response_setup_baton,
                                            apr_pool_t *pool)
{
    client_ctx_t *cctx = request_baton;
    apr_pool_t *request_pool;
    request_ctx_t *rctx;

    *req_bkt = serf_bucket_incoming_request_create(stream, stream->allocator);

    apr_pool_create(&request_pool, cctx->pool);

    rctx = apr_pcalloc(request_pool, sizeof(*rctx));
    rctx->client = cctx;

    *handler = request_handler;
    *handler_baton = rctx;

    *response_setup = request_generate_response;
    *response_setup_baton = rctx;

    return APR_SUCCESS;
}


static apr_status_t client_accept(serf_context_t *ctx,
                                  serf_listener_t *l,
                                  void *accept_baton,
                                  apr_socket_t *insock,
                                  apr_pool_t *pool)
{
    serf_incoming_t *client;
    listener_ctx_t *lctx = accept_baton;
    apr_pool_t *cctx_pool;
    client_ctx_t *cctx;
    apr_status_t status;

    apr_pool_create(&cctx_pool, pool);
    cctx = apr_pcalloc(cctx_pool, sizeof(*cctx));
    cctx->pool = cctx_pool;
    cctx->listener = lctx;

    status = serf_incoming_create2(&client, ctx, insock,
                                   client_setup, cctx,
                                   client_closed, cctx,
                                   client_request_acceptor, cctx,
                                   pool);
    if (status)
        return status;

    if (lctx->proto && !strcmp(lctx->proto, "fcgi")) {
        serf_incoming_set_framing_type(client,
                                       SERF_CONNECTION_FRAMING_TYPE_FCGI);
    }
    else if (lctx->proto && !strcmp(lctx->proto, "h2c")) {
        serf_incoming_set_framing_type(client,
                                       SERF_CONNECTION_FRAMING_TYPE_HTTP2);
    }
    else if (lctx->proto && !strcmp(lctx->proto, "http1")) {
        serf_incoming_set_framing_type(client,
                                       SERF_CONNECTION_FRAMING_TYPE_HTTP1);
    }

    return status;
}


/* Value for 'no short code' should be > 255 */
#define CERTFILE 256
#define CERTPWD  257
#define HTTP2FLAG 258
#define H2DIRECT 259

static const apr_getopt_option_t options[] =
{

    { "help",    'h', 0, "Display this help" },
    { "version", 'V', 0, "Display version" },
    { "listen",  'l', 1, "<[protocol,][host:]port> Configure listener"},
    { "verbose", 'v', 0, "Enable debug logging" },
/*    { NULL,      'H', 0, "Print response headers" },
    { NULL,      'n', 1, "<count> Fetch URL <count> times" },
    { NULL,      'c', 1, "<count> Use <count> concurrent connections" },
    { NULL,   'x', 1, "<count> Number of maximum outstanding requests inflight" },
    { "user",    'U', 1, "<user> Username for Basic/Digest authentication" },
    { "pwd",     'P', 1, "<password> Password for Basic/Digest authentication" },
    { NULL,      'm', 1, "<method> Use the <method> HTTP Method" },
    { NULL,      'f', 1, "<file> Use the <file> as the request body" },
    { NULL,      'p', 1, "<hostname:port> Use the <host:port> as proxy server" },
    { "cert",    CERTFILE, 1, "<file> Use SSL client certificate <file>" },
    { "certpwd", CERTPWD, 1, "<password> Password for the SSL client certificate" },
    { NULL,      'r', 1, "<header:value> Use <header:value> as request header" },
    { "http2",   HTTP2FLAG, 0, "Enable http2 (https only) (Experimental)" },
    { "h2direct",H2DIRECT, 0, "Enable h2direct (Experimental)" },*/

    { NULL, 0 }
};

static void print_usage(apr_pool_t *pool)
{
    int i = 0;

    puts("serf_httpd [options] directory\n");
    puts("Options:");

    while (options[i].optch > 0) {
        const apr_getopt_option_t* o = &options[i];

        if (o->optch <= 255) {
            printf(" -%c", o->optch);
            if (o->name)
                printf(", ");
        }
        else {
            printf("     ");
        }

        printf("%s%s\t%s\n",
               o->name ? "--" : "\t",
               o->name ? o->name : "",
               o->description);

        i++;
    }
}

static void configure_listener(serf_context_t *ctx,
                               app_ctx_t *app,
                               const char *arg,
                               apr_pool_t *pool)
{
    const char *listen_spec;
    char *addr = NULL;
    char *scope_id = NULL;
    apr_port_t port;
    apr_status_t status;
    listener_ctx_t *lctx;
    serf_listener_t *listener;

    char *comma = strchr(arg, ',');

    listen_spec = comma ? comma + 1 : arg;

    status = apr_parse_addr_port(&addr, &scope_id, &port, listen_spec, pool);
    if (status) {
        printf("Error parsing listen address: %s\n", listen_spec);
        exit(1);
    }

    if (!addr) {
        addr = "0.0.0.0";
    }

    if (port == 0) {
        port = 8080;
    }

    lctx = apr_pcalloc(pool, sizeof(*lctx));
    lctx->app = app;

    if (comma)
        lctx->proto = apr_pstrmemdup(pool, arg, comma - arg);

    status = serf_listener_create(&listener, ctx, addr, port, lctx,
                                  client_accept, pool);
    if (status) {
        printf("Error creating listener '%s': %d", listen_spec, status);
        exit(1);
    }
}

int main(int argc, const char **argv)
{
    apr_status_t status;
    apr_pool_t *app_pool;
    apr_pool_t *scratch_pool;
    serf_context_t *context;
    app_ctx_t app_ctx;
    apr_getopt_t *opt;
    apr_allocator_t *allocator;
    int opt_c;
    int verbose = 0;
    const char *opt_arg;
    const char *root_dir;

    apr_initialize();
    atexit(apr_terminate);

    apr_pool_create(&app_pool, NULL);

    apr_pool_abort_set(pool_abort_func, app_pool);

    /* Keep a maximum of 16 MB unused memory inside APR. */
    allocator = apr_pool_allocator_get(app_pool);
    if (allocator != NULL)
        apr_allocator_max_free_set(allocator, 16384 * 1024);
    /* else: APR pool debugging... leave this to apr */

    apr_signal(SIGINT, signal_handler);
#ifdef SIGBREAK
    /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
    apr_signal(SIGBREAK, signal_handler);
#endif
#ifdef SIGHUP
    apr_signal(SIGHUP, signal_handler);
#endif
#ifdef SIGTERM
    apr_signal(SIGTERM, signal_handler);
#endif

#ifdef SIGPIPE
    /* Disable SIGPIPE generation for the platforms that have it. */
    apr_signal(SIGPIPE, SIG_IGN);
#endif


    apr_pool_create(&scratch_pool, app_pool);

    apr_getopt_init(&opt, scratch_pool, argc, argv);
    context = serf_context_create(app_pool);

    apr_getopt_init(&opt, scratch_pool, argc, argv);
    while ((status = apr_getopt_long(opt, options, &opt_c, &opt_arg)) ==
           APR_SUCCESS) {
        switch (opt_c) {
            case 'h':
                print_usage(scratch_pool);
                exit(0);
                break;
            case 'V':
                puts("Serf version: " SERF_VERSION_STRING);
                exit(0);
            case 'l':
                configure_listener(context, &app_ctx, opt_arg, app_pool);
                break;
            case 'v':
                verbose++;
                break;

            default:
                break;
        }
    }

    if (opt->ind != opt->argc - 1) {
        print_usage(scratch_pool);
        exit(-1);
    }

    root_dir = argv[opt->ind];

    /* Setup debug logging */
    if (verbose) {
        serf_log_output_t *output;
        apr_status_t status;
        apr_uint32_t level;

        level = SERF_LOG_WARNING;
        if (verbose >= 3)
            level = SERF_LOG_DEBUG;
        else if (verbose >= 2)
            level = SERF_LOG_INFO;

        status = serf_logging_create_stream_output(
            &output,
            context,
            level,
            SERF_LOGCOMP_ALL_MSG & ~(SERF_LOGCOMP_RAWMSG | SERF_LOGCOMP_SSLMSG),
            SERF_LOG_DEFAULT_LAYOUT,
            stderr,
            app_pool);

        if (!status)
            serf_logging_add_output(context, output);
    }

    while (1) {
        apr_pool_clear(scratch_pool);
        status = serf_context_run(context, apr_time_from_msec(50),
                                  scratch_pool);
        if (APR_STATUS_IS_TIMEUP(status)) {
            if (cancelled)
                break;
            else
                continue;
        }
        if (status) {
            char buf[200];
            const char *err_string;
            err_string = serf_error_string(status);
            if (!err_string) {
                err_string = apr_strerror(status, buf, sizeof(buf));
            }

            printf("Error running context: (%d) %s\n", status, err_string);
            apr_pool_destroy(app_pool);
            exit(1);
        }
    }

    apr_pool_destroy(app_pool);
    return 0;
}
