/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

#include "android/utils/aconfig-file.h"
#include "android/utils/eintr_wrapper.h"
#include "android/utils/path.h"

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

AConfig*
aconfig_node(const char *name, const char *value)
{
    AConfig *n;

    n = (AConfig*) calloc(sizeof(AConfig), 1);
    n->name = name ? name : "";
    n->value = value ? value : "";

    return n;
}

void
aconfig_node_free(AConfig *root) {
    AConfig *node, *next;
    for (node = root->first_child; node; node = next) {
        next = node->next;
        aconfig_node_free(node);
    }
    free(node);
}

static AConfig* _aconfig_find_create(AConfig* root, const char* name) {
    AConfig *node;

    for(node = root->first_child; node; node = node->next) {
        if (!strcmp(node->name, name)) {
            return node;
        }
    }

    node = aconfig_node(name, NULL);

    if (root->last_child) {
        root->last_child->next = node;
    } else {
        root->first_child = node;
    }
    root->last_child = node;

    return node;
}

const AConfig* aconfig_find_const(const AConfig* root, const char* name) {
    const AConfig* node;

    for (node = root->first_child; node; node = node->next) {
        if (!strcmp(node->name, name))
            return node;
    }

    return NULL;
}

AConfig* aconfig_find(AConfig* root, const char* name) {
    return (AConfig*)aconfig_find_const(root, name);
}

int aconfig_bool(const AConfig* root, const char* name, int _default) {
    const AConfig* n = aconfig_find_const(root, name);
    if(n == 0) {
        return _default;
    } else {
        switch(n->value[0]){
        case 'y':
        case 'Y':
        case '1':
        case 't':
        case 'T':
            return 1;
        default:
            return 0;
        }
    }
}

unsigned aconfig_unsigned(const AConfig* root,
                          const char* name,
                          unsigned _default) {
    const AConfig* n = aconfig_find_const(root, name);
    if(n == 0) {
        return _default;
    } else {
        return strtoul(n->value, 0, 0);
    }
}

int aconfig_int(const AConfig* root, const char* name, int _default) {
    const AConfig* n = aconfig_find_const(root, name);
    if(n == 0) {
        return _default;
    } else {
        return strtol(n->value, 0, 0);
    }
}

const char* aconfig_str(const AConfig* root,
                        const char* name,
                        const char* _default) {
    const AConfig* n = aconfig_find_const(root, name);
    if(n == 0) {
        return _default;
    } else {
        return n->value;
    }
}

void
aconfig_set(AConfig *root, const char *name, const char *value)
{
    AConfig* node = _aconfig_find_create(root, name);
    node->value = value;
}

#define T_EOF 0
#define T_TEXT 1
#define T_DOT 2
#define T_OBRACE 3
#define T_CBRACE 4

typedef struct
{
    char *data;
    char *text;
    int len;
    char next;
} cstate;


static int _lex(cstate *cs, int value)
{
    char c;
    char *s;
    char *data;

    data = cs->data;

    if(cs->next != 0) {
        c = cs->next;
        cs->next = 0;
        goto got_c;
    }

restart:
    for(;;) {
        c = *data++;
    got_c:
        if(isspace(c)) continue;

        switch(c) {
        case 0:
            return T_EOF;

        /* a sharp sign (#) starts a line comment and everything
         * behind that is ignored until the end of line
         */
        case '#':
            for(;;) {
                switch(*data) {
                case 0:
                    cs->data = data;
                    return T_EOF;
                case '\n':
                    cs->data = data + 1;
                    goto restart;
                default:
                    data++;
                }
            }
            break;

        case '.':
            cs->data = data;
            return T_DOT;

        case '{':
            cs->data = data;
            return T_OBRACE;

        case '}':
            cs->data = data;
            return T_CBRACE;

        default:
            s = data - 1;

            if(value) {
               /* if we're looking for a value, then take anything
                * until the end of line. note that sharp signs do
                * not start comments then. the result will be stripped
                * from trailing whitespace.
                */
                for(;;) {
                    if(*data == 0) {
                        cs->data = data;
                        break;
                    }
                    if(*data == '\n') {
                        cs->data = data + 1;
                        *data-- = 0;
                        break;
                    }
                    data++;
                }

                    /* strip trailing whitespace */
                while(data > s){
                    if(!isspace(*data)) break;
                    *data-- = 0;
                }

                goto got_text;
            } else {
               /* looking for a key name. we stop at whitespace,
                * EOF, of T_DOT/T_OBRACE/T_CBRACE characters.
                * note that the name can include sharp signs
                */
                for(;;) {
                    if(isspace(*data)) {
                        *data = 0;
                        cs->data = data + 1;
                        goto got_text;
                    }
                    switch(*data) {
                    case 0:
                        cs->data = data;
                        goto got_text;
                    case '.':
                    case '{':
                    case '}':
                        cs->next = *data;
                        *data = 0;
                        cs->data = data + 1;
                        goto got_text;
                    default:
                        data++;
                    }
                }
            }
        }
    }

got_text:
    cs->text = s;
    return T_TEXT;
}

#if 0
char *TOKENNAMES[] = { "EOF", "TEXT", "DOT", "OBRACE", "CBRACE" };

static int lex(cstate *cs, int value)
{
    int tok = _lex(cs, value);
    printf("TOKEN(%d) %s %s\n", value, TOKENNAMES[tok],
           tok == T_TEXT ? cs->text : "");
    return tok;
}
#else
#define lex(cs,v) _lex(cs,v)
#endif

static int parse_expr(cstate *cs, AConfig *node);

static int
parse_block(cstate *cs, AConfig *node)
{
    for(;;){
        switch(lex(cs, 0)){
        case T_TEXT:
            if(parse_expr(cs, node)) return -1;
            continue;

        case T_CBRACE:
            return 0;

        default:
            return -1;
        }
    }
}

static int
parse_expr(cstate *cs, AConfig *node)
{
        /* last token was T_TEXT */
        node = _aconfig_find_create(node, cs->text);

        for (;;) {
            switch (lex(cs, 1)) {
                case T_DOT:
                    if (lex(cs, 0) != T_TEXT)
                        return -1;
                    node = _aconfig_find_create(node, cs->text);
                    continue;

                case T_TEXT:
                    node->value = cs->text;
                    return 0;

                case T_OBRACE:
                    return parse_block(cs, node);

                default:
                    return -1;
            }
    }
}

void
aconfig_load(AConfig *root, char *data)
{
    if(data != 0) {
        cstate cs;
        cs.data = data;
        cs.next = 0;

        for(;;) {
            switch(lex(&cs, 0)){
            case T_TEXT:
                if(parse_expr(&cs, root)) return;
                break;
            default:
                return;
            }
        }
    }
}

int
aconfig_load_file(AConfig *root, const char *fn)
{
    char *data;
    data = path_load_file(fn, NULL);
    if (data == NULL)
        return -1;

    aconfig_load(root, data);
    return 0;
}


typedef struct
{
    char   buff[1024];
    char*  p;
    char*  end;
    int    fd;
} Writer;

static int
writer_init( Writer*  w, const char*  fn )
{
    w->p   = w->buff;
    w->end = w->buff + sizeof(w->buff);

    w->fd  = creat( fn, 0755 );
    if (w->fd < 0)
        return -1;

#ifdef _WIN32
    _setmode( w->fd, _O_BINARY );
#endif
    return 0;
}

static void
writer_write( Writer*  w, const char*  src, int  len )
{
    while (len > 0) {
        int  avail = w->end - w->p;

        if (avail > len)
            avail = len;

        memcpy( w->p, src, avail );
        src += avail;
        len -= avail;

        w->p += avail;
        if (w->p == w->end) {
            if (HANDLE_EINTR(write(w->fd, w->buff, w->p - w->buff)) < 0)
                break;
            w->p = w->buff;
        }
    }
}

static void
writer_done( Writer*  w )
{
    if (w->p > w->buff) {
        HANDLE_EINTR(write(w->fd, w->buff, w->p - w->buff));
    }
    IGNORE_EINTR(close( w->fd ));
}

static void
writer_margin( Writer*  w, int  margin)
{
    static const char  spaces[10] = "          ";
    while (margin >= 10) {
        writer_write(w,spaces,10);
        margin -= 10;
    }
    if (margin > 0)
        writer_write(w,spaces,margin);
}

static void
writer_c(Writer*  w, char  c)
{
    writer_write(w, &c, 1);
}

static void
writer_str(Writer*  w, const char*  str)
{
    writer_write(w, str, strlen(str));
}

static void writer_node(Writer* w, const AConfig* node, int margin) {
    writer_margin(w,margin);
    writer_str(w, node->name);
    writer_c(w,' ');

    if (node->value[0]) {
        writer_str(w, node->value);
        writer_c(w,'\n');
    }
    else
    {
        AConfig*  child;

        writer_c(w, '{');
        writer_c(w, '\n');

        for (child = node->first_child; child; child = child->next)
            writer_node(w,child,margin+4);

        writer_margin(w,margin);
        writer_c(w,'}');
        writer_c(w,'\n');
    }
}

int aconfig_save_file(const AConfig* root, const char* fn) {
    AConfig*  child;
    Writer    w[1];

    if (writer_init(w,fn) < 0)
        return -1;

    for (child = root->first_child; child; child = child->next)
        writer_node(w,child,0);

    writer_done(w);
    return 0;
}
