/*
 * Copyright (C) 2011 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.
 */

#define LOG_TAG "str_params"
//#define LOG_NDEBUG 0

#define _GNU_SOURCE 1
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <cutils/hashmap.h>
#include <cutils/log.h>
#include <cutils/memory.h>

#include <cutils/str_parms.h>

struct str_parms {
    Hashmap *map;
};


static bool str_eq(void *key_a, void *key_b)
{
    return !strcmp((const char *)key_a, (const char *)key_b);
}

/* use djb hash unless we find it inadequate */
static int str_hash_fn(void *str)
{
    uint32_t hash = 5381;
    char *p;

    for (p = str; p && *p; p++)
        hash = ((hash << 5) + hash) + *p;
    return (int)hash;
}

struct str_parms *str_parms_create(void)
{
    struct str_parms *str_parms;

    str_parms = calloc(1, sizeof(struct str_parms));
    if (!str_parms)
        return NULL;

    str_parms->map = hashmapCreate(5, str_hash_fn, str_eq);
    if (!str_parms->map)
        goto err;

    return str_parms;

err:
    free(str_parms);
    return NULL;
}

static bool remove_pair(void *key, void *value, void *context)
{
    struct str_parms *str_parms = context;

    hashmapRemove(str_parms->map, key);
    free(key);
    free(value);
    return true;
}

void str_parms_destroy(struct str_parms *str_parms)
{
    hashmapForEach(str_parms->map, remove_pair, str_parms);
    hashmapFree(str_parms->map);
    free(str_parms);
}

struct str_parms *str_parms_create_str(const char *_string)
{
    struct str_parms *str_parms;
    char *str;
    char *kvpair;
    char *tmpstr;
    int items = 0;

    str_parms = str_parms_create();
    if (!str_parms)
        goto err_create_str_parms;

    str = strdup(_string);
    if (!str)
        goto err_strdup;

    ALOGV("%s: source string == '%s'\n", __func__, _string);

    kvpair = strtok_r(str, ";", &tmpstr);
    while (kvpair && *kvpair) {
        char *eq = strchr(kvpair, '='); /* would love strchrnul */
        char *value;
        char *key;
        void *old_val;

        if (eq == kvpair)
            goto next_pair;

        if (eq) {
            key = strndup(kvpair, eq - kvpair);
            if (*(++eq))
                value = strdup(eq);
            else
                value = strdup("");
        } else {
            key = strdup(kvpair);
            value = strdup("");
        }

        /* if we replaced a value, free it */
        old_val = hashmapPut(str_parms->map, key, value);
        if (old_val)
            free(old_val);

        items++;
next_pair:
        kvpair = strtok_r(NULL, ";", &tmpstr);
    }

    if (!items)
        ALOGV("%s: no items found in string\n", __func__);

    free(str);

    return str_parms;

err_strdup:
    str_parms_destroy(str_parms);
err_create_str_parms:
    return NULL;
}

void str_parms_del(struct str_parms *str_parms, const char *key)
{
    hashmapRemove(str_parms->map, (void *)key);
}

int str_parms_add_str(struct str_parms *str_parms, const char *key,
                      const char *value)
{
    void *old_val;
    void *tmp_key;
    void *tmp_val;

    tmp_key = strdup(key);
    tmp_val = strdup(value);
    old_val = hashmapPut(str_parms->map, tmp_key, tmp_val);

    if (old_val) {
        free(old_val);
    } else if (errno == ENOMEM) {
        free(tmp_key);
        free(tmp_val);
        return -ENOMEM;
    }
    return 0;
}

int str_parms_add_int(struct str_parms *str_parms, const char *key, int value)
{
    char val_str[12];
    int ret;

    ret = snprintf(val_str, sizeof(val_str), "%d", value);
    if (ret < 0)
        return -EINVAL;

    ret = str_parms_add_str(str_parms, key, val_str);
    return ret;
}

int str_parms_add_float(struct str_parms *str_parms, const char *key,
                        float value)
{
    char val_str[23];
    int ret;

    ret = snprintf(val_str, sizeof(val_str), "%.10f", value);
    if (ret < 0)
        return -EINVAL;

    ret = str_parms_add_str(str_parms, key, val_str);
    return ret;
}

int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
                      int len)
{
    char *value;

    value = hashmapGet(str_parms->map, (void *)key);
    if (value)
        return strlcpy(val, value, len);

    return -ENOENT;
}

int str_parms_get_int(struct str_parms *str_parms, const char *key, int *val)
{
    char *value;
    char *end;

    value = hashmapGet(str_parms->map, (void *)key);
    if (!value)
        return -ENOENT;

    *val = (int)strtol(value, &end, 0);
    if (*value != '\0' && *end == '\0')
        return 0;

    return -EINVAL;
}

int str_parms_get_float(struct str_parms *str_parms, const char *key,
                        float *val)
{
    float out;
    char *value;
    char *end;

    value = hashmapGet(str_parms->map, (void *)key);
    if (!value)
        return -ENOENT;

    out = strtof(value, &end);
    if (*value != '\0' && *end == '\0')
        return 0;

    return -EINVAL;
}

static bool combine_strings(void *key, void *value, void *context)
{
    char **old_str = context;
    char *new_str;
    int ret;

    ret = asprintf(&new_str, "%s%s%s=%s",
                   *old_str ? *old_str : "",
                   *old_str ? ";" : "",
                   (char *)key,
                   (char *)value);
    if (*old_str)
        free(*old_str);

    if (ret >= 0) {
        *old_str = new_str;
        return true;
    }

    *old_str = NULL;
    return false;
}

char *str_parms_to_str(struct str_parms *str_parms)
{
    char *str = NULL;

    if (hashmapSize(str_parms->map) > 0)
        hashmapForEach(str_parms->map, combine_strings, &str);
    else
        str = strdup("");
    return str;
}

static bool dump_entry(void *key, void *value, void *context)
{
    ALOGI("key: '%s' value: '%s'\n", (char *)key, (char *)value);
    return true;
}

void str_parms_dump(struct str_parms *str_parms)
{
    hashmapForEach(str_parms->map, dump_entry, str_parms);
}

#ifdef TEST_STR_PARMS
static void test_str_parms_str(const char *str)
{
    struct str_parms *str_parms;
    char *out_str;
    int ret;

    str_parms = str_parms_create_str(str);
    str_parms_add_str(str_parms, "dude", "woah");
    str_parms_dump(str_parms);
    out_str = str_parms_to_str(str_parms);
    str_parms_destroy(str_parms);
    ALOGI("%s: '%s' stringified is '%s'", __func__, str, out_str);
    free(out_str);
}

int main(void)
{
    struct str_parms *str_parms;

    test_str_parms_str("");
    test_str_parms_str(";");
    test_str_parms_str("=");
    test_str_parms_str("=;");
    test_str_parms_str("=bar");
    test_str_parms_str("=bar;");
    test_str_parms_str("foo=");
    test_str_parms_str("foo=;");
    test_str_parms_str("foo=bar");
    test_str_parms_str("foo=bar;");
    test_str_parms_str("foo=bar;baz");
    test_str_parms_str("foo=bar;baz=");
    test_str_parms_str("foo=bar;baz=bat");
    test_str_parms_str("foo=bar;baz=bat;");

    return 0;
}
#endif
