/* Copyright (C) 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/ini.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "android/utils/debug.h"
#include "android/utils/system.h" /* for ASTRDUP */
#include "android/utils/bufprint.h"
#include "osdep.h"

/* W() is used to print warnings, D() to print debugging info */
#define  W(...)   dwarning(__VA_ARGS__)
#define  D(...)   VERBOSE_PRINT(avd_config,__VA_ARGS__)

/* a simple .ini file parser and container for Android
 * no sections support. see android/utils/ini.h for
 * more details on the supported file format.
 */
typedef struct {
    char*  key;
    char*  value;
} IniPair;

struct IniFile {
    int       numPairs;
    int       maxPairs;
    IniPair*  pairs;
};

void
iniFile_free( IniFile*  i )
{
    int  nn;
    for (nn = 0; nn < i->numPairs; nn++) {
        AFREE(i->pairs[nn].key);
        i->pairs[nn].key   = NULL;
        i->pairs[nn].value = NULL;
    }
    AFREE(i->pairs);
    AFREE(i);
}

static IniFile*
iniFile_alloc( void )
{
    IniFile*  i;

    ANEW0(i);
    return i;
}

static void
iniPair_init( IniPair* pair, const char* key, int keyLen,
                             const char* value, int valueLen )
{
    AARRAY_NEW(pair->key, keyLen + valueLen + 2);
    memcpy(pair->key, key, keyLen);
    pair->key[keyLen] = 0;

    pair->value = pair->key + keyLen + 1;
    memcpy(pair->value, value, valueLen);
    pair->value[valueLen] = 0;
}

static void
iniPair_replaceValue( IniPair* pair, const char* value )
{
    char* key      = pair->key;
    int   keyLen   = strlen(key);
    int   valueLen = strlen(value);

    iniPair_init(pair, key, keyLen, value, valueLen);
    AFREE(key);
}

static void
iniFile_addPair( IniFile*  i,
                 const char*  key,   int  keyLen,
                 const char*  value, int  valueLen )
{
    IniPair*  pair;

    if (i->numPairs >= i->maxPairs) {
        int       oldMax = i->maxPairs;
        int       newMax = oldMax + (oldMax >> 1) + 4;

        AARRAY_RENEW(i->pairs, newMax);
        i->maxPairs = newMax;
    }

    pair = i->pairs + i->numPairs;
    iniPair_init(pair, key, keyLen, value, valueLen);

    i->numPairs += 1;
}

static IniPair*
iniFile_getPair( IniFile* i, const char* key )
{
    if (i && key) {
        int  nn;

        for (nn = 0; nn < i->numPairs; nn++) {
            if (!strcmp(i->pairs[nn].key,key))
                return &i->pairs[nn];
        }
    }
    return NULL;
}

const char*
iniFile_getValue( IniFile*  i, const char*  key )
{
    IniPair* pair = iniFile_getPair(i, key);
    if (pair)
        return pair->value;
    else
        return NULL;
}

int
iniFile_getPairCount( IniFile*  i )
{
    return i ? i->numPairs : 0;
}

/* NOTE: we avoid using <ctype.h> functions to avoid locale-specific
 *       behaviour that can be the source of strange bugs.
 */

static const char*
skipSpaces( const char* p )
{
    while (*p == ' ' || *p == '\t')
        p ++;
    return p;
}

static const char*
skipToEOL( const char*  p )
{
    while (*p && (*p != '\n' && *p != '\r'))
        p ++;

    if (*p) {
        p ++;
        if (p[-1] == '\r' && p[0] == '\n')
            p ++;
    }
    return p;
}

static int
isKeyStartChar( int  c )
{
    return ((unsigned)(c-'a') < 26 ||
            (unsigned)(c-'A') < 26 ||
            c == '_');
}

static int
isKeyChar( int  c )
{
    return isKeyStartChar(c) || ((unsigned)(c-'0') < 10) || (c == '.') || (c == '-');
}

IniFile*
iniFile_newFromMemory( const char*  text, const char*  fileName )
{
    const char*  p      = text;
    IniFile*     ini    = iniFile_alloc();
    int          lineno = 0;

    if (!fileName)
        fileName = "<memoryFile>";

    D("%s: parsing as .ini file", fileName);

    while (*p) {
        const char*  key;
        int          keyLen;
        const char*  value;
        int          valueLen;

        lineno += 1;

        /* skip leading whitespace */
        p = skipSpaces(p);

        /* skip comments and empty lines */
        if (*p == 0 || *p == ';' || *p == '#' || *p == '\n' || *p == '\r') {
            p = skipToEOL(p);
            continue;
        }

        /* check the key name */
        key = p++;
        if (!isKeyStartChar(*key)) {
            p = skipToEOL(p);
            W("%4d: key name doesn't start with valid character. line ignored",
              lineno);
            continue;
        }

        while (isKeyChar(*p))
            p++;

        keyLen = p - key;
        p      = skipSpaces(p);

        /* check the equal */
        if (*p != '=') {
            W("%4d: missing expected assignment operator (=). line ignored",
              lineno);
            p = skipToEOL(p);
            continue;
        }
        p += 1;

        /* skip spaces before the value */
        p     = skipSpaces(p);
        value = p;

        /* find the value */
        while (*p && (*p != '\n' && *p != '\r'))
            p += 1;

        /* remove trailing spaces */
        while (p > value && (p[-1] == ' ' || p[-1] == '\t'))
            p --;

        valueLen = p - value;

        iniFile_addPair(ini, key, keyLen, value, valueLen);
        D("%4d: KEY='%.*s' VALUE='%.*s'", lineno,
          keyLen, key, valueLen, value);

        p = skipToEOL(p);
    }

    D("%s: parsing finished", fileName);

    return ini;
}

IniFile*
iniFile_newFromFile( const char*  filepath )
{
    FILE*        fp = fopen(filepath, "rt");
    char*        text;
    long         size;
    IniFile*     ini = NULL;
    size_t       len;

    if (fp == NULL) {
        D("could not open .ini file: %s: %s",
          filepath, strerror(errno));
        return NULL;
    }

    fseek(fp, 0, SEEK_END);
    size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    /* avoid reading a very large file that was passed by mistake
     * this threshold is quite liberal.
     */
#define  MAX_INI_FILE_SIZE  655360

    if (size < 0 || size > MAX_INI_FILE_SIZE) {
        W("hardware configuration file '%s' too large (%ld bytes)",
          filepath, size);
        goto EXIT;
    }

    /* read the file, add a sentinel at the end of it */
    AARRAY_NEW(text, size+1);
    len = fread(text, 1, size, fp);
    text[len] = 0;

    ini = iniFile_newFromMemory(text, filepath);
    AFREE(text);

EXIT:
    fclose(fp);
    return ini;
}

/* Common routine for saving IniFile instance to the given file.
 * Param:
 *  f - IniFile instance to save.
 *  filepath - Path to a file where to save the instance.
 *  strip - If 1, ignore (don't save) pairs with empty values. If 0, save all
 *      pairs found in the IniFile instance, including the ones that contain
 *      empty values.
 * Returns:
 *  0 on success, -1 on error (see errno for error code)
 */
static int
iniFile_saveToFileCommon( IniFile*  f, const char*  filepath, int strip )
{
    FILE*  fp = fopen(filepath, "wt");
    IniPair*  pair    = f->pairs;
    IniPair*  pairEnd = pair + f->numPairs;
    int       result  = 0;

    if (fp == NULL) {
        D("could not create .ini file: %s: %s",
          filepath, strerror(errno));
        return -1;
    }

    for ( ; pair < pairEnd; pair++ ) {
        if ((pair->value && *pair->value) || !strip) {
            char  temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
            p = bufprint(temp, end, "%s = %s\n", pair->key, pair->value);
            if (fwrite(temp, p - temp, 1, fp) != 1) {
                result = -1;
                break;
            }
        }
    }

    fclose(fp);
    return result;
}

int
iniFile_saveToFile( IniFile*  f, const char*  filepath )
{
    return iniFile_saveToFileCommon(f, filepath, 0);
}

int
iniFile_saveToFileClean( IniFile*  f, const char*  filepath )
{
    return iniFile_saveToFileCommon(f, filepath, 1);
}

int
iniFile_getEntry(IniFile* f, int index, char** key, char** value)
{
    if (index >= f->numPairs) {
        D("Index %d exceeds the number of ini file entries %d",
          index, f->numPairs);
        return -1;
    }

    *key = ASTRDUP(f->pairs[index].key);
    *value = ASTRDUP(f->pairs[index].value);

    return 0;
}

char*
iniFile_getString( IniFile*  f, const char*  key, const char* defaultValue )
{
    const char*  val = iniFile_getValue(f, key);

    if (!val) {
        if (!defaultValue)
            return NULL;
        val= defaultValue;
    }

    return ASTRDUP(val);
}

int
iniFile_getInteger( IniFile*  f, const char*  key, int  defaultValue )
{
    const char*  valueStr = iniFile_getValue(f, key);
    int          value    = defaultValue;

    if (valueStr != NULL) {
        char*  end;
        long   l = strtol(valueStr, &end, 10);
        if (end != NULL && end[0] == 0 && (int)l == l)
            value = l;
    }
    return value;
}

double
iniFile_getDouble( IniFile*  f, const char*  key, double  defaultValue )
{
    const char*  valueStr = iniFile_getValue(f, key);
    double       value    = defaultValue;

    if (valueStr != NULL) {
        char*   end;
        double  d = strtod(valueStr, &end);
        if (end != NULL && end[0] == 0)
            value = d;
    }
    return value;
}

int
iniFile_getBoolean( IniFile*  f, const char*  key, const char*  defaultValue )
{
    const char*  value  = iniFile_getValue(f, key);

    if (!value)
        value = defaultValue;

    if (!strcmp(value,"1")    ||
        !strcmp(value,"yes")  ||
        !strcmp(value,"YES")  ||
        !strcmp(value,"true") ||
        !strcmp(value,"TRUE"))
    {
        return 1;
    }
    else
        return 0;
}

int64_t
iniFile_getDiskSize( IniFile*  f, const char*  key, const char*  defaultValue )
{
    const char*  valStr = iniFile_getValue(f, key);
    int64_t      value  = 0;

    if (!valStr)
        valStr = defaultValue;

    if (valStr != NULL) {
        char*  end;

        value = strtoll(valStr, &end, 10);
        if (*end == 'k' || *end == 'K')
            value *= 1024ULL;
        else if (*end == 'm' || *end == 'M')
            value *= 1024*1024ULL;
        else if (*end == 'g' || *end == 'G')
            value *= 1024*1024*1024ULL;
    }
    return value;
}

int64_t
iniFile_getInt64( IniFile*  f, const char*  key, int64_t  defaultValue )
{
    const char*  valStr = iniFile_getValue(f, key);
    int64_t      value  = defaultValue;

    if (valStr != NULL) {
        char*    end;
        int64_t  d;

        d = strtoll(valStr, &end, 10);
        if (end != NULL && end[0] == 0)
            value = d;
    }
    return value;
}

void
iniFile_setValue( IniFile* f, const char* key, const char* value )
{
    IniPair* pair;

    if (f == NULL || key == NULL || value == NULL)
        return;

    pair = iniFile_getPair(f, key);
    if (pair != NULL) {
        iniPair_replaceValue(pair, value);
    } else {
        iniFile_addPair(f, key, strlen(key), value, strlen(value));
    }
}

void
iniFile_setInteger( IniFile* f, const char* key, int value )
{
    char temp[16];
    snprintf(temp, sizeof temp, "%d", value);
    iniFile_setValue(f, key, temp);
}

void
iniFile_setInt64( IniFile* f, const char* key, int64_t value )
{
    char temp[32];
    snprintf(temp, sizeof temp, "%" PRId64, value);
    iniFile_setValue(f, key, temp);
}

void
iniFile_setDouble( IniFile* f, const char* key, double value )
{
    char temp[32];
    snprintf(temp, sizeof temp, "%g", value);
    iniFile_setValue(f, key, temp);
}

void
iniFile_setBoolean( IniFile* f, const char* key, int value )
{
    iniFile_setValue(f, key, value ? "yes" : "no");
}

void
iniFile_setDiskSize( IniFile* f, const char* key, int64_t size )
{
    char     temp[32];
    int64_t  divisor = 0;
    const int64_t  kilo = 1024;
    const int64_t  mega = 1024*kilo;
    const int64_t  giga = 1024*mega;
    char     suffix = '\0';

    if (size >= giga && !(size % giga)) {
        divisor = giga;
        suffix = 'g';
    }
    else if (size >= mega && !(size % mega)) {
        divisor = mega;
        suffix  = 'm';
    }
    else if (size >= kilo && !(size % kilo)) {
        divisor = kilo;
        suffix = 'k';
    }
    if (divisor) {
        snprintf(temp, sizeof temp, "%" PRId64 "%c", size/divisor, suffix);
    } else {
        snprintf(temp, sizeof temp, "%" PRId64, size);
    }
    iniFile_setValue(f, key, temp);
}
