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

/*
 * httxt2dbm.c: simple program for converting RewriteMap text files to DBM
 * Rewrite databases for the Apache HTTP server
 *
 */

#include "apr.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_file_io.h"
#include "apr_file_info.h"
#include "apr_pools.h"
#include "apr_getopt.h"
#include "apu.h"
#include "apr_dbm.h"

#if APR_HAVE_STDLIB_H
#include <stdlib.h> /* for atexit() */
#endif

static const char *input;
static const char *output;
static const char *format;
static const char *shortname;
static apr_file_t *errfile;
static int verbose;

/* From mod_rewrite.c */
#ifndef REWRITE_MAX_TXT_MAP_LINE
#define REWRITE_MAX_TXT_MAP_LINE 1024
#endif

#define NL APR_EOL_STR

#define AVAIL "available"
#define UNAVAIL "unavailable"

static void usage(void)
{
    const char *have_sdbm;
    const char *have_gdbm;
    const char *have_ndbm;
    const char *have_db;

#if APU_HAVE_SDBM
    have_sdbm = AVAIL;
#else
    have_sdbm = UNAVAIL;
#endif
#if APU_HAVE_GDBM
    have_gdbm = AVAIL;
#else
    have_gdbm = UNAVAIL;
#endif
#if APU_HAVE_NDBM
    have_ndbm = AVAIL;
#else
    have_ndbm = UNAVAIL;
#endif
#if APU_HAVE_DB
    have_db = AVAIL;
#else
    have_db = UNAVAIL;
#endif

    apr_file_printf(errfile,
    "%s -- Program to Create DBM Files for use by RewriteMap" NL
    "Usage: %s [-v] [-f format] -i SOURCE_TXT -o OUTPUT_DBM" NL
    NL
    "Options: " NL
    " -v    More verbose output" NL
    NL
    " -i    Source Text File. If '-', use stdin." NL
    NL
    " -o    Output DBM." NL
    NL
    " -f    DBM Format.  If not specified, will use the APR Default." NL
    "           GDBM for GDBM files (%s)" NL
    "           SDBM for SDBM files (%s)" NL
    "           DB   for berkeley DB files (%s)" NL
    "           NDBM for NDBM files (%s)" NL
    "           default for the default DBM type" NL
    NL,
    shortname,
    shortname,
    have_gdbm,
    have_sdbm,
    have_db,
    have_ndbm);
}


static apr_status_t to_dbm(apr_dbm_t *dbm, apr_file_t *fp, apr_pool_t *pool)
{
    apr_status_t rv = APR_SUCCESS;
    char line[REWRITE_MAX_TXT_MAP_LINE + 1]; /* +1 for \0 */
    apr_datum_t dbmkey;
    apr_datum_t dbmval;
    apr_pool_t* p;

    apr_pool_create(&p, pool);

    while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) {
        char *c, *value;

        if (*line == '#' || apr_isspace(*line)) {
            continue;
        }

        c = line;

        while (*c && !apr_isspace(*c)) {
            ++c;
        }

        if (!*c) {
            /* no value. solid line of data. */
            continue;
        }

        dbmkey.dptr = apr_pstrmemdup(p, line,  c - line);
        dbmkey.dsize = (c - line);

        while (apr_isspace(*c)) {
            ++c;
        }

        if (!*c) {
            apr_pool_clear(p);
            continue;
        }

        value = c;

        while (*c && !apr_isspace(*c)) {
            ++c;
        }

        dbmval.dptr = apr_pstrmemdup(p, value,  c - value);
        dbmval.dsize = (c - value);

        if (verbose) {
            apr_file_printf(errfile, "    '%s' -> '%s'" NL,
                            dbmkey.dptr, dbmval.dptr);
        }

        rv = apr_dbm_store(dbm, dbmkey, dbmval);

        apr_pool_clear(p);

        if (rv != APR_SUCCESS) {
            break;
        }
    }

    return rv;
}

int main(int argc, const char *const argv[])
{
    apr_pool_t *pool;
    apr_status_t rv = APR_SUCCESS;
    apr_getopt_t *opt;
    const char *opt_arg;
    char ch;
    apr_file_t *infile;
    apr_dbm_t *outdbm;

    apr_app_initialize(&argc, &argv, NULL);
    atexit(apr_terminate);

    verbose = 0;
    format = NULL;
    input = NULL;
    output = NULL;

    apr_pool_create(&pool, NULL);

    if (argc) {
        shortname = apr_filepath_name_get(argv[0]);
    }
    else {
        shortname = "httxt2dbm";
    }

    apr_file_open_stderr(&errfile, pool);
    rv = apr_getopt_init(&opt, pool, argc, argv);

    if (rv != APR_SUCCESS) {
        apr_file_printf(errfile, "Error: apr_getopt_init failed." NL NL);
        return 1;
    }

    if (argc <= 1) {
        usage();
        return 1;
    }

    while ((rv = apr_getopt(opt, "vf::i::o::", &ch, &opt_arg)) == APR_SUCCESS) {
        switch (ch) {
        case 'v':
            if (verbose) {
                apr_file_printf(errfile, "Error: -v can only be passed once" NL NL);
                usage();
                return 1;
            }
            verbose = 1;
            break;
        case 'f':
            if (format) {
                apr_file_printf(errfile, "Error: -f can only be passed once" NL NL);
                usage();
                return 1;
            }
            format = apr_pstrdup(pool, opt_arg);
            break;
        case 'i':
            if (input) {
                apr_file_printf(errfile, "Error: -i can only be passed once" NL NL);
                usage();
                return 1;
            }
            input = apr_pstrdup(pool, opt_arg);
            break;
        case 'o':
            if (output) {
                apr_file_printf(errfile, "Error: -o can only be passed once" NL NL);
                usage();
                return 1;
            }
            output = apr_pstrdup(pool, opt_arg);
            break;
        }
    }

    if (rv != APR_EOF) {
        apr_file_printf(errfile, "Error: Parsing Arguments Failed" NL NL);
        usage();
        return 1;
    }

    if (!input) {
        apr_file_printf(errfile, "Error: No input file specified." NL NL);
        usage();
        return 1;
    }

    if (!output) {
        apr_file_printf(errfile, "Error: No output DBM specified." NL NL);
        usage();
        return 1;
    }

    if (!format) {
        format = "default";
    }

    if (verbose) {
        apr_file_printf(errfile, "DBM Format: %s" NL, format);
    }

    if (!strcmp(input, "-")) {
        rv = apr_file_open_stdin(&infile, pool);
    }
    else {
        rv = apr_file_open(&infile, input, APR_READ|APR_BUFFERED,
                           APR_OS_DEFAULT, pool);
    }

    if (rv != APR_SUCCESS) {
        apr_file_printf(errfile,
                        "Error: Cannot open input file '%s': (%d) %pm" NL NL,
                         input, rv, &rv);
        return 1;
    }

    if (verbose) {
        apr_file_printf(errfile, "Input File: %s" NL, input);
    }

    rv = apr_dbm_open_ex(&outdbm, format, output, APR_DBM_RWCREATE,
                    APR_OS_DEFAULT, pool);

    if (APR_STATUS_IS_ENOTIMPL(rv)) {
        apr_file_printf(errfile,
                        "Error: The requested DBM Format '%s' is not available." NL NL,
                         format);
        return 1;
    }

    if (rv != APR_SUCCESS) {
        apr_file_printf(errfile,
                        "Error: Cannot open output DBM '%s': (%d) %pm" NL NL,
                         output, rv, &rv);
        return 1;
    }

    if (verbose) {
        apr_file_printf(errfile, "DBM File: %s" NL, output);
    }

    rv = to_dbm(outdbm, infile, pool);

    if (rv != APR_SUCCESS) {
        apr_file_printf(errfile,
                        "Error: Converting to DBM: (%d) %pm" NL NL,
                         rv, &rv);
        return 1;
    }

    apr_dbm_close(outdbm);

    if (verbose) {
        apr_file_printf(errfile, "Conversion Complete." NL);
    }

    return 0;
}

