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

/*
 * Originally written @ BBC by Graham Leggett
 * Copyright 2009-2011 British Broadcasting Corporation
 *
 */

#include "apr.h"
#include "apr_lib.h"
#include "apr_buckets.h"
#include "apr_file_io.h"
#include "apr_file_info.h"
#include "apr_hash.h"
#include "apr_poll.h"
#include "apr_portable.h"
#include "apr_getopt.h"
#include "apr_signal.h"
#include "apr_strings.h"
#include "apr_uuid.h"
#if APR_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif

#include "ap_release.h"

#define DEFAULT_MAXLINES 0
#define DEFAULT_MAXSIZE 0
#define DEFAULT_AGE 0 * 1000 * 1000
#define DEFAULT_PREFIX 0
#define DEFAULT_NONBLOCK 0

typedef struct file_rec
{
    apr_pool_t *pool;
    apr_file_t *file_err;
    apr_file_t *file_in;
    apr_file_t *file_out;
    const char *directory;
    apr_bucket_alloc_t *alloc;
    apr_bucket_brigade *bb;
    apr_hash_t *request_uuids;
    apr_hash_t *response_uuids;
    apr_hash_t *filters;
    int limit;
    apr_size_t skipped_bytes;
    apr_size_t dropped_fragments;
    apr_time_t start;
    apr_time_t end;
} file_rec;

typedef struct uuid_rec
{
    apr_pool_t *pool;
    const char *uuid;
    file_rec *file;
    apr_uint64_t count;
    apr_time_t last;
    apr_size_t offset;
    int direction;
} uuid_rec;

typedef struct filter_rec
{
    apr_pool_t *pool;
    const char *prefix;
    apr_size_t len;
} filter_rec;

typedef struct header_rec
{
    apr_size_t len;
    apr_time_t timestamp;
    int direction;
    char uuid[APR_UUID_FORMATTED_LENGTH + 1];
    apr_uint64_t count;
    uuid_rec *rec;
} header_rec;

static const apr_getopt_option_t
        cmdline_opts[] =
        {
                /* commands */
                {
                        "file",
                        'f',
                        1,
                        "   --file, -f <name>\t\t\tFile to read the firehose from.\n\t\t\t\t\tDefaults to stdin." },
                {
                        "output-directory",
                        'd',
                        1,
                        "   --output-directory, -o <name>\tDirectory to write demuxed connections\n\t\t\t\t\tto." },
                {
                        "uuid",
                        'u',
                        1,
                        "   --uuid, -u <uuid>\t\t\tThe UUID of the connection to\n\t\t\t\t\tdemultiplex. Can be specified more\n\t\t\t\t\tthan once." },
                /*				{ "output-host", 'h', 1,
                 "   --output-host, -h <hostname>\tHostname to write demuxed connections to." },*/
                /*				{
                 "speed",
                 's',
                 1,
                 "   --speed, -s <factor>\tSpeed up or slow down demuxing\n\t\t\t\tby the given factor." },*/
                { "help", 258, 0, "   --help, -h\t\t\t\tThis help text." },
                { "version", 257, 0,
                        "   --version\t\t\t\tDisplay the version of the program." },
                { NULL } };

#define HELP_HEADER "Usage : %s [options] [prefix1 [prefix2 ...]]\n\n" \
                    "Firehose demultiplexes the given stream of multiplexed connections, and\n" \
                    "writes each connection to a file, or to a socket as appropriate.\n" \
                    "\n" \
                    "When writing to files, each connection is placed into a dedicated file\n" \
                    "named after the UUID of the connection within the stream. Separate files\n" \
                    "will be created if requests and responses are found in the stream.\n" \
                    "\n" \
                    "If an optional prefix is specified as a parameter, connections that start\n" \
                    "with the given prefix will be included. The prefix needs to fit completely\n" \
                    "within the first fragment for a successful match to occur.\n" \
                    "\n"
/*                    "When writing to a socket, new connections\n"
 *                    "are opened for each connection in the stream, allowing it to be possible to\n"
 *                    "'replay' traffic recorded by one server to other server.\n"
 *                    "\n\n"
 */
#define HELP_FOOTER ""

/**
 * Who are we again?
 */
static void version(const char * const progname)
{
    printf("%s (%s)\n", progname, AP_SERVER_VERSION);
}

/**
 * Help the long suffering end user.
 */
static void help(const char *argv, const char * header, const char *footer,
        const apr_getopt_option_t opts[])
{
    int i = 0;

    if (header) {
        printf(header, argv);
    }

    while (opts[i].name) {
        printf("%s\n", opts[i].description);
        i++;
    }

    if (footer) {
        printf("%s\n", footer);
    }
}

/**
 * Cleanup a uuid record. Removes the record from the uuid hashtable in files.
 */
static apr_status_t cleanup_uuid_rec(void *dummy)
{
    uuid_rec *rec = (uuid_rec *) dummy;

    if (rec->direction == '>') {
        apr_hash_set(rec->file->response_uuids, rec->uuid, APR_HASH_KEY_STRING,
                NULL);
    }
    if (rec->direction == '<') {
        apr_hash_set(rec->file->request_uuids, rec->uuid, APR_HASH_KEY_STRING,
                NULL);
    }

    return APR_SUCCESS;
}

/**
 * Create a uuid record, register a cleanup for it's destruction.
 */
static apr_status_t make_uuid_rec(file_rec *file, header_rec *header,
        uuid_rec **ptr)
{
    apr_pool_t *pool;
    uuid_rec *rec;
    apr_pool_create(&pool, file->pool);

    rec = apr_pcalloc(pool, sizeof(uuid_rec));
    rec->pool = pool;
    rec->file = file;
    rec->uuid = apr_pstrdup(pool, header->uuid);
    rec->count = 0;
    rec->last = header->timestamp;
    rec->direction = header->direction;

    if (header->direction == '>') {
        apr_hash_set(file->response_uuids, rec->uuid, APR_HASH_KEY_STRING, rec);
    }
    if (header->direction == '<') {
        apr_hash_set(file->request_uuids, rec->uuid, APR_HASH_KEY_STRING, rec);
    }

    apr_pool_cleanup_register(pool, rec, cleanup_uuid_rec, cleanup_uuid_rec);

    *ptr = rec;
    return APR_SUCCESS;
}

/**
 * Process the end of the fragment body.
 *
 * This function renames the completed stream to it's final name.
 */
static apr_status_t finalise_body(file_rec *file, header_rec *header)
{
    apr_status_t status;
    char *nfrom, *nto, *from, *to;
    apr_pool_t *pool;

    apr_pool_create(&pool, file->pool);

    to = apr_pstrcat(pool, header->uuid, header->direction == '>' ? ".response"
            : ".request", NULL);
    from = apr_pstrcat(pool, to, ".part", NULL);

    status = apr_filepath_merge(&nfrom, file->directory, from,
            APR_FILEPATH_SECUREROOT, pool);
    if (APR_SUCCESS == status) {
        status = apr_filepath_merge(&nto, file->directory, to,
                APR_FILEPATH_SECUREROOT, pool);
        if (APR_SUCCESS == status) {
            if (APR_SUCCESS == (status = apr_file_mtime_set(nfrom, file->end, pool))) {
                if (APR_SUCCESS != (status = apr_file_rename(nfrom, nto, pool))) {
                    apr_file_printf(
                            file->file_err,
                            "Could not rename file '%s' to '%s' for fragment write: %pm\n",
                            nfrom, nto, &status);
                }
            }
            else {
                apr_file_printf(
                        file->file_err,
                        "Could not set mtime on file '%s' to '%" APR_TIME_T_FMT "' for fragment write: %pm\n",
                        nfrom, file->end, &status);
            }
        }
        else {
            apr_file_printf(file->file_err,
                    "Could not merge directory '%s' with file '%s': %pm\n",
                    file->directory, to, &status);
        }
    }
    else {
        apr_file_printf(file->file_err,
                "Could not merge directory '%s' with file '%s': %pm\n",
                file->directory, from, &status);
    }

    apr_pool_destroy(pool);

    return status;
}

/**
 * Check if the fragment matches on of the prefixes.
 */
static int check_prefix(file_rec *file, header_rec *header, const char *str,
        apr_size_t len)
{
    apr_hash_index_t *hi;
    void *val;
    apr_pool_t *pool;
    int match = -1;

    apr_pool_create(&pool, file->pool);

    for (hi = apr_hash_first(pool, file->filters); hi; hi = apr_hash_next(hi)) {
        filter_rec *filter;
        apr_hash_this(hi, NULL, NULL, &val);
        filter = (filter_rec *) val;

        if (len > filter->len && !strncmp(filter->prefix, str, filter->len)) {
            match = 1;
            break;
        }
        match = 0;
    }

    apr_pool_destroy(pool);

    return match;
}

/**
 * Process part of the fragment body, given the header parameters.
 *
 * Currently, we append it to a file named after the UUID of the connection.
 *
 * The file is opened on demand and closed when done, so that we are
 * guaranteed never to hit a file handle limit (within reason).
 */
static apr_status_t process_body(file_rec *file, header_rec *header,
        const char *str, apr_size_t len)
{
    apr_status_t status;
    char *native, *name;
    apr_pool_t *pool;
    apr_file_t *handle;

    if (!file->start) {
        file->start = header->timestamp;
    }
    file->end = header->timestamp;

    apr_pool_create(&pool, file->pool);

    name
            = apr_pstrcat(pool, header->uuid,
                    header->direction == '>' ? ".response.part"
                            : ".request.part", NULL);

    status = apr_filepath_merge(&native, file->directory, name,
            APR_FILEPATH_SECUREROOT, pool);
    if (APR_SUCCESS == status) {
        if (APR_SUCCESS == (status = apr_file_open(&handle, native, APR_WRITE
                | APR_CREATE | APR_APPEND, APR_OS_DEFAULT, pool))) {
            if (APR_SUCCESS != (status = apr_file_write_full(handle, str, len,
                    NULL))) {
                apr_file_printf(file->file_err,
                        "Could not write fragment body to file '%s': %pm\n",
                        native, &status);
            }
        }
        else {
            apr_file_printf(file->file_err,
                    "Could not open file '%s' for fragment write: %pm\n",
                    native, &status);
        }
    }
    else {
        apr_file_printf(file->file_err,
                "Could not merge directory '%s' with file '%s': %pm\n",
                file->directory, name, &status);
    }

    apr_pool_destroy(pool);

    return status;
}

/**
 * Parse a chunk extension, detect overflow.
 * There are two error cases:
 *  1) If the conversion would require too many bits, a -1 is returned.
 *  2) If the conversion used the correct number of bits, but an overflow
 *     caused only the sign bit to flip, then that negative number is
 *     returned.
 * In general, any negative number can be considered an overflow error.
 */
static apr_status_t read_hex(const char **buf, apr_uint64_t *val)
{
    const char *b = *buf;
    apr_uint64_t chunksize = 0;
    apr_size_t chunkbits = sizeof(apr_uint64_t) * 8;

    if (!apr_isxdigit(*b)) {
        return APR_EGENERAL;
    }
    /* Skip leading zeros */
    while (*b == '0') {
        ++b;
    }

    while (apr_isxdigit(*b) && (chunkbits > 0)) {
        int xvalue = 0;

        if (*b >= '0' && *b <= '9') {
            xvalue = *b - '0';
        }
        else if (*b >= 'A' && *b <= 'F') {
            xvalue = *b - 'A' + 0xa;
        }
        else if (*b >= 'a' && *b <= 'f') {
            xvalue = *b - 'a' + 0xa;
        }

        chunksize = (chunksize << 4) | xvalue;
        chunkbits -= 4;
        ++b;
    }
    *buf = b;
    if (apr_isxdigit(*b) && (chunkbits <= 0)) {
        /* overflow */
        return APR_EGENERAL;
    }

    *val = chunksize;

    return APR_SUCCESS;
}

/**
 * Parse what might be a fragment header line.
 *
 * If the parse doesn't match for any reason, an error is returned, otherwise
 * APR_SUCCESS.
 *
 * The header structure will be filled with the header values as parsed.
 */
static apr_status_t process_header(file_rec *file, header_rec *header,
        const char *str, apr_size_t len)
{
    apr_uint64_t val;
    apr_status_t status;
    int i;
    apr_uuid_t raw;
    const char *end = str + len;

    if (APR_SUCCESS != (status = read_hex(&str, &val))) {
        return status;
    }
    header->len = val;

    if (!apr_isspace(*(str++))) {
        return APR_EGENERAL;
    }

    if (APR_SUCCESS != (status = read_hex(&str, &val))) {
        return status;
    }
    header->timestamp = val;

    if (!apr_isspace(*(str++))) {
        return APR_EGENERAL;
    }

    if (*str != '<' && *str != '>') {
        return APR_EGENERAL;
    }
    header->direction = *str;
    str++;

    if (!apr_isspace(*(str++))) {
        return APR_EGENERAL;
    }

    for (i = 0; str[i] && i < APR_UUID_FORMATTED_LENGTH; i++) {
        header->uuid[i] = str[i];
    }
    header->uuid[i] = 0;
    if (apr_uuid_parse(&raw, header->uuid)) {
        return APR_EGENERAL;
    }
    str += i;

    if (!apr_isspace(*(str++))) {
        return APR_EGENERAL;
    }

    if (APR_SUCCESS != (status = read_hex(&str, &val))) {
        return status;
    }
    header->count = val;

    if ((*(str++) != '\r')) {
        return APR_EGENERAL;
    }
    if ((*(str++) != '\n')) {
        return APR_EGENERAL;
    }
    if (str != end) {
        return APR_EGENERAL;
    }

    return APR_SUCCESS;
}

/**
 * Suck on the file/pipe, and demux any fragments on the incoming stream.
 *
 * If EOF is detected, this function returns.
 */
static apr_status_t demux(file_rec *file)
{
    apr_size_t len = 0;
    apr_status_t status = APR_SUCCESS;
    apr_bucket *b, *e;
    apr_bucket_brigade *bb, *obb;
    int footer = 0;
    const char *buf;

    bb = apr_brigade_create(file->pool, file->alloc);
    obb = apr_brigade_create(file->pool, file->alloc);
    b = apr_bucket_pipe_create(file->file_in, file->alloc);

    APR_BRIGADE_INSERT_HEAD(bb, b);

    do {

        /* when the pipe is closed, the pipe disappears from the brigade */
        if (APR_BRIGADE_EMPTY(bb)) {
            break;
        }

        status = apr_brigade_split_line(obb, bb, APR_BLOCK_READ,
                HUGE_STRING_LEN);

        if (APR_SUCCESS == status || APR_EOF == status) {
            char str[HUGE_STRING_LEN];
            len = HUGE_STRING_LEN;

            apr_brigade_flatten(obb, str, &len);

            apr_brigade_cleanup(obb);

            if (len == HUGE_STRING_LEN) {
                file->skipped_bytes += len;
                continue;
            }
            else if (footer) {
                if (len == 2 && str[0] == '\r' && str[1] == '\n') {
                    footer = 0;
                    continue;
                }
                file->skipped_bytes += len;
            }
            else if (len > 0) {
                header_rec header;
                status = process_header(file, &header, str, len);
                if (APR_SUCCESS != status) {
                    file->skipped_bytes += len;
                    continue;
                }
                else {
                    int ignore = 0;

                    header.rec = NULL;
                    if (header.direction == '>') {
                        header.rec = apr_hash_get(file->response_uuids,
                                header.uuid, APR_HASH_KEY_STRING);
                    }
                    if (header.direction == '<') {
                        header.rec = apr_hash_get(file->request_uuids,
                                header.uuid, APR_HASH_KEY_STRING);
                    }
                    if (header.rec) {
                        /* does the count match what is expected? */
                        if (header.count != header.rec->count) {
                            file->dropped_fragments++;
                            ignore = 1;
                        }
                    }
                    else {
                        /* must we ignore unknown uuids? */
                        if (file->limit) {
                            ignore = 1;
                        }

                        /* is the counter not what we expect? */
                        else if (header.count != 0) {
                            file->skipped_bytes += len;
                            ignore = 1;
                        }

                        /* otherwise, make a new uuid */
                        else {
                            make_uuid_rec(file, &header, &header.rec);
                        }
                    }

                    if (header.len) {
                        if (APR_SUCCESS != (status = apr_brigade_partition(bb,
                                header.len, &e))) {
                            apr_file_printf(
                                    file->file_err,
                                    "Could not read fragment body from input file: %pm\n", &status);
                            break;
                        }
                        while ((b = APR_BRIGADE_FIRST(bb)) && e != b) {
                            apr_bucket_read(b, &buf, &len, APR_READ_BLOCK);
                            if (!ignore && !header.count && !check_prefix(file,
                                    &header, buf, len)) {
                                ignore = 1;
                            }
                            if (!ignore) {
                                status = process_body(file, &header, buf, len);
                                header.rec->offset += len;
                            }
                            if (ignore || APR_SUCCESS != status) {
                                apr_bucket_delete(b);
                                file->skipped_bytes += len;
                                continue;
                            }
                            apr_bucket_delete(b);
                        }
                        if (!ignore) {
                            header.rec->count++;
                        }
                        footer = 1;
                        continue;
                    }
                    else {
                        /* an empty header means end-of-connection */
                        if (header.rec) {
                            if (!ignore) {
                                if (!header.count) {
                                    status = process_body(file, &header, "", 0);
                                }
                                status = finalise_body(file, &header);
                            }
                            apr_pool_destroy(header.rec->pool);
                        }
                    }

                }
            }

        }
        else {
            apr_file_printf(file->file_err,
                    "Could not read fragment header from input file: %pm\n", &status);
            break;
        }

    } while (1);

    return status;
}

/**
 * Start the application.
 */
int main(int argc, const char * const argv[])
{
    apr_status_t status;
    apr_pool_t *pool;
    apr_getopt_t *opt;
    int optch;
    const char *optarg;

    file_rec *file;

    /* lets get APR off the ground, and make sure it terminates cleanly */
    if (APR_SUCCESS != (status = apr_app_initialize(&argc, &argv, NULL))) {
        return 1;
    }
    atexit(apr_terminate);

    if (APR_SUCCESS != (status = apr_pool_create(&pool, NULL))) {
        return 1;
    }

#ifdef SIGPIPE
    apr_signal_block(SIGPIPE);
#endif

    file = apr_pcalloc(pool, sizeof(file_rec));
    apr_file_open_stderr(&file->file_err, pool);
    apr_file_open_stdin(&file->file_in, pool);
    apr_file_open_stdout(&file->file_out, pool);

    file->pool = pool;
    file->alloc = apr_bucket_alloc_create(pool);
    file->bb = apr_brigade_create(pool, file->alloc);
    file->request_uuids = apr_hash_make(pool);
    file->response_uuids = apr_hash_make(pool);
    file->filters = apr_hash_make(pool);

    apr_getopt_init(&opt, pool, argc, argv);
    while ((status = apr_getopt_long(opt, cmdline_opts, &optch, &optarg))
            == APR_SUCCESS) {

        switch (optch) {
        case 'f': {
            status = apr_file_open(&file->file_in, optarg, APR_FOPEN_READ,
                    APR_OS_DEFAULT, pool);
            if (status != APR_SUCCESS) {
                apr_file_printf(file->file_err,
                        "Could not open file '%s' for read: %pm\n", optarg, &status);
                return 1;
            }
            break;
        }
        case 'd': {
            apr_finfo_t finfo;
            status = apr_stat(&finfo, optarg, APR_FINFO_TYPE, pool);
            if (status != APR_SUCCESS) {
                apr_file_printf(file->file_err,
                        "Directory '%s' could not be found: %pm\n", optarg, &status);
                return 1;
            }
            if (finfo.filetype != APR_DIR) {
                apr_file_printf(file->file_err,
                        "Path '%s' isn't a directory\n", optarg);
                return 1;
            }
            file->directory = optarg;
            break;
        }
        case 'u': {
            apr_pool_t *pchild;
            uuid_rec *rec;
            apr_pool_create(&pchild, pool);
            rec = apr_pcalloc(pchild, sizeof(uuid_rec));
            rec->pool = pchild;
            rec->uuid = optarg;
            apr_hash_set(file->request_uuids, optarg, APR_HASH_KEY_STRING, rec);
            apr_hash_set(file->response_uuids, optarg, APR_HASH_KEY_STRING, rec);
            file->limit++;
            break;
        }
        case 257: {
            version(argv[0]);
            return 0;
        }
        case 258: {
            help(argv[0], HELP_HEADER, HELP_FOOTER, cmdline_opts);
            return 0;

        }
        }

    }
    if (APR_SUCCESS != status && APR_EOF != status) {
        return 1;
    }

    /* read filters from the command line */
    while (opt->ind < argc) {
        apr_pool_t *pchild;
        filter_rec *filter;
        apr_pool_create(&pchild, pool);
        filter = apr_pcalloc(pchild, sizeof(filter_rec));
        filter->pool = pchild;
        filter->prefix = opt->argv[opt->ind];
        filter->len = strlen(opt->argv[opt->ind]);
        apr_hash_set(file->filters, opt->argv[opt->ind], APR_HASH_KEY_STRING,
                filter);
        opt->ind++;
    }

    status = demux(file);

    /* warn people if any non blocking writes failed */
    if (file->skipped_bytes || file->dropped_fragments) {
        apr_file_printf(
                file->file_err,
                "Warning: %" APR_SIZE_T_FMT " bytes skipped, %" APR_SIZE_T_FMT " fragments dropped.\n",
                file->skipped_bytes, file->dropped_fragments);
    }

    if (APR_SUCCESS != status) {
        return 1;
    }

    return 0;
}
