/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  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.
 */

/***************************************************************************
 * Description: DSAPI plugin for Lotus Domino                              *
 * Author:      Andy Armstrong <andy@tagish.com>                           *
 * Date:        20010603                                                   *
 * Version:     $Revision$                                           *
 ***************************************************************************/

#include "config.h"
#include "inifile.h"
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* We have one of these for each ini file line. Once we've read the
 * file and parsed it we'll have an array in key order containing one
 * of these for each configuration item in file.
 */
typedef struct
{
    const char *key;
    const char *value;

} inifile_key;

static char *file;              /* the text of the ini file                             */
static inifile_key *keys;       /* an array of keys, one per item               */
static size_t klen;             /* length of the key array                              */

/* Text that will prefix all of our error messages */
#define ERRPFX "INIFILE: "
/* Various error messages that we can return */
ERRTYPE inifile_outofmemory = ERRPFX "Out of memory";
ERRTYPE inifile_filenotfound = ERRPFX "File not found";
ERRTYPE inifile_readerror = ERRPFX "Error reading file";
#define SYNFMT ERRPFX "File %s, line %d: %s"

/* Case insensitive string comparison, works like strcmp() */
static int inifile__stricmp(const char *s1, const char *s2)
{
    while (*s1 && tolower(*s1) == tolower(*s2))
        s1++, s2++;
    return tolower(*s1) - tolower(*s2);
}

/* Compare keys, suitable for passing to qsort() */
static int inifile__cmp(const void *k1, const void *k2)
{
    const inifile_key *kk1 = (const inifile_key *)k1;
    const inifile_key *kk2 = (const inifile_key *)k2;
    return inifile__stricmp(kk1->key, kk2->key);
}

/* Return a new syntax error message. */
static ERRTYPE inifile__syntax(jk_pool_t *p, const char *file, int line,
                               const char *msg)
{
    static const char synfmt[] = SYNFMT;
    size_t len =
        sizeof(synfmt) + strlen(msg) + strlen(file) +
        10 /* fudge for line number */ ;
    char *buf = jk_pool_alloc(p, len);
    sprintf(buf, synfmt, file, line, msg);
    return buf;
}

/* Various macros to tidy up the parsing code */

/* Characters that are OK in the keyname */
#define KEYCHR(c) \
	(isalnum(c) || (c) == '.' || (c) == '_')

/* Skip whitespace */
#define SKIPSPC() \
	while (*fp == '\t' || *fp == ' ') fp++

/* Skip to the end of the current line */
#define SKIPLN() \
	while (*fp != '\0' && *fp != '\r' && *fp != '\n') fp++

/* Move from the end of the current line to the start of the next, learning what the
 * newline character is and counting lines
 */
#define NEXTLN() \
	do { while (*fp == '\r' || *fp == '\n') { if (nlc == -1) nlc = *fp; if (*fp == nlc) ln++; fp++; } } while (0)

/* Build the index. Called when the inifile is loaded by inifile_load()
 */
static ERRTYPE inifile__index(jk_pool_t *p, const char *name)
{
    int pass;
    int ln = 1;
    int nlc = -1;

    /* Make two passes over the data. First time we're just counting
     * the lines that contain values so we can allocate the index, second
     * time we build the index.
     */
    for (pass = 0; pass < 2; pass++) {
        char *fp = file;
        char *ks = NULL, *ke;   /* key start, end */
        char *vs = NULL, *ve;   /* value start, end */
        klen = 0;

        while (*fp != '\0') {
            SKIPSPC();

            /* turn a comment into an empty line by moving to the next \r|\n */
            if (*fp == '#' || *fp == ';')
                SKIPLN();

            if (*fp != '\0' && *fp != '\r' && *fp != '\n') {
                ks = fp;        /* start of key */
                while (KEYCHR(*fp))
                    fp++;
                ke = fp;        /* end of key */
                SKIPSPC();

                if (*fp != '=')
                    return inifile__syntax(p, name, ln,
                                           "Missing '=' or illegal character in key");

                fp++;           /* past the = */
                SKIPSPC();
                vs = fp;
                SKIPLN();
                ve = fp;
                /* back up over any trailing space */
                while (ve > vs && (ve[-1] == ' ' || ve[-1] == '\t'))
                    ve--;
                NEXTLN();       /* move forwards *before* we trash the eol characters */

                if (NULL != keys) {     /* second pass? if so stash a pointer */
                    *ke = '\0';
                    *ve = '\0';
                    keys[klen].key = ks;
                    keys[klen].value = vs;
                }

                klen++;
            }
            else {
                NEXTLN();
            }
        }

        if (NULL == keys
            && (keys =
                jk_pool_alloc(p, sizeof(inifile_key) * klen), NULL == keys))
            return inifile_outofmemory;
    }

    /* got the index now, sort it so we can search it quickly */
    qsort(keys, klen, sizeof(inifile_key), inifile__cmp);

    return ERRNONE;
}

/* Read an INI file from disk
 */
ERRTYPE inifile_read(jk_pool_t *p, const char *name)
{
    FILE *fl;
    size_t flen;
    int ok;

    if (fl = fopen(name, "rb"), NULL == fl)
        return inifile_filenotfound;

    fseek(fl, 0L, SEEK_END);
    flen = (size_t) ftell(fl);
    fseek(fl, 0L, SEEK_SET);

    /* allocate one extra byte for trailing \0
     */
    if (file = jk_pool_alloc(p, flen + 1), NULL == file) {
        fclose(fl);
        return inifile_outofmemory;
    }

    ok = (fread(file, flen, 1, fl) == 1);
    fclose(fl);
    if (!ok)
        return inifile_readerror;

    file[flen] = '\0';          /* terminate it to simplify parsing */

    return inifile__index(p, name);
}

/* Find the value associated with the given key returning it or NULL
 * if no match is found. Key name matching is case insensitive.
 */
const char *inifile_lookup(const char *key)
{
    int lo, mid, hi, cmp;

    if (NULL == keys)
        return NULL;

    for (lo = 0, hi = klen - 1; lo <= hi;) {
        mid = (lo + hi) / 2;
        cmp = inifile__stricmp(key, keys[mid].key);
        if (cmp < 0)            /* key in array is greater */
            hi = mid - 1;
        else if (cmp > 0)
            lo = mid + 1;
        else
            return keys[mid].value;
    }

    return NULL;
}

#ifdef TEST

static jk_pool_t pool;
extern void jk_dump_pool(jk_pool_t *p, FILE * f);       /* not declared in header */

int main(void)
{
    ERRTYPE e;
    unsigned k;
    int rc = 0;

    jk_open_pool(&pool, NULL, 0);

    e = inifile_read(&pool, "ok.ini");
    if (e == ERRNONE) {
        printf("%u keys in ok.ini\n", klen);
        for (k = 0; k < klen; k++) {
            const char *val = inifile_lookup(keys[k].key);
            printf("Key: \"%s\", value: \"%s\"\n", keys[k].key, val);
        }
    }
    else {
        printf("Error reading ok.ini: %s\n", e);
        rc = 1;
    }

    e = inifile_read(&pool, "bad.ini");
    if (e == ERRNONE) {
        printf("%u keys in bad.ini\n", klen);
        for (k = 0; k < klen; k++) {
            const char *val = inifile_lookup(keys[k].key);
            printf("Key: \"%s\", value: \"%s\"\n", keys[k].key, val);
        }
        rc = 1;                 /* should be a syntax error */
    }
    else {
        printf
            ("Error reading bad.ini: %s (which is OK: that's what we expected)\n",
             e);
    }

    jk_dump_pool(&pool, stdout);
    jk_close_pool(&pool);

    return rc;
}
#endif
