/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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.
 */

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

#include <cutils/config_utils.h>
#include <cutils/misc.h>

cnode* config_node(const char *name, const char *value)
{
    cnode *node;

    node = calloc(sizeof(cnode), 1);
    if(node) {
        node->name = name ? name : "";
        node->value = value ? value : "";
    }

    return node;
}

cnode* config_find(cnode *root, const char *name)
{
    cnode *node, *match = NULL;

    /* we walk the whole list, as we need to return the last (newest) entry */
    for(node = root->first_child; node; node = node->next)
        if(!strcmp(node->name, name))
            match = node;

    return match;
}

static cnode* _config_create(cnode *root, const char *name)
{
    cnode *node;

    node = config_node(name, NULL);

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

    root->last_child = node;

    return node;
}

int config_bool(cnode *root, const char *name, int _default)
{
    cnode *node;
        
    node = config_find(root, name);
    if(!node)
        return _default;

    switch(node->value[0]) {
    case 'y':
    case 'Y':
    case '1':
        return 1;
    default:
        return 0;
    }
}

const char* config_str(cnode *root, const char *name, const char *_default)
{
    cnode *node;

    node = config_find(root, name);
    if(!node)
        return _default;
    return node->value;
}

void config_set(cnode *root, const char *name, const char *value)
{
    cnode *node;

    node = config_find(root, name);
    if(node)
        node->value = value;
    else {
        node = _config_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;

        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) {
                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 {
                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, cnode *node);

static int parse_block(cstate *cs, cnode *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, cnode *root)
{
    cnode *node;

        /* last token was T_TEXT */
    node = config_find(root, cs->text);
    if(!node || *node->value)
        node = _config_create(root, cs->text);

    for(;;) {
        switch(lex(cs, 1)) {
        case T_DOT:
            if(lex(cs, 0) != T_TEXT)
                return -1;
            node = _config_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 config_load(cnode *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;
            }
        }
    }
}

void config_load_file(cnode *root, const char *fn)
{
    char *data;
    data = load_file(fn, 0);
    config_load(root, data);
}

void config_free(cnode *root)
{
    cnode *cur = root->first_child;

    while (cur) {
        cnode *prev = cur;
        config_free(cur);
        cur = cur->next;
        free(prev);
    }
}
