/* 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 "qemu/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);
}
