/*
 * 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.
 */

#include <cutils/str_parms.h>

#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/memory.h>
#include <log/log.h>

#define UNUSED __attribute__((unused))

/* When an object is allocated but not freed in a function,
 * because its ownership is released to other object like a hashmap,
 * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid
 * false warnings about potential memory leak.
 * For now, a "temporary" assignment to global variables
 * is enough to confuse the clang static analyzer.
 */
#ifdef __clang_analyzer__
static void *released_pointer;
#define RELEASE_OWNERSHIP(x) { released_pointer = x; released_pointer = 0; }
#else
#define RELEASE_OWNERSHIP(x)
#endif

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 */
#ifdef __clang__
__attribute__((no_sanitize("integer")))
#endif
static int str_hash_fn(void *str)
{
    uint32_t hash = 5381;

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

struct str_parms *str_parms_create(void)
{
    str_parms* s = static_cast<str_parms*>(calloc(1, sizeof(str_parms)));
    if (!s) return NULL;

    s->map = hashmapCreate(5, str_hash_fn, str_eq);
    if (!s->map) {
        free(s);
        return NULL;
    }

    return s;
}

struct remove_ctxt {
    struct str_parms *str_parms;
    const char *key;
};

static bool remove_pair(void *key, void *value, void *context)
{
    remove_ctxt* ctxt = static_cast<remove_ctxt*>(context);
    bool should_continue;

    /*
     * - if key is not supplied, then we are removing all entries,
     *   so remove key and continue (i.e. return true)
     * - if key is supplied and matches, then remove it and don't
     *   continue (return false). Otherwise, return true and keep searching
     *   for key.
     *
     */
    if (!ctxt->key) {
        should_continue = true;
        goto do_remove;
    } else if (!strcmp(ctxt->key, static_cast<const char*>(key))) {
        should_continue = false;
        goto do_remove;
    }

    return true;

do_remove:
    hashmapRemove(ctxt->str_parms->map, key);
    free(key);
    free(value);
    return should_continue;
}

void str_parms_del(struct str_parms *str_parms, const char *key)
{
    struct remove_ctxt ctxt = {
        .str_parms = str_parms,
        .key = key,
    };
    hashmapForEach(str_parms->map, remove_pair, &ctxt);
}

void str_parms_destroy(struct str_parms *str_parms)
{
    struct remove_ctxt ctxt = {
        .str_parms = str_parms,
    };

    hashmapForEach(str_parms->map, remove_pair, &ctxt);
    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);
        RELEASE_OWNERSHIP(value);
        if (old_val) {
            free(old_val);
            free(key);
        } else {
            RELEASE_OWNERSHIP(key);
        }

        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;
}

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

    // strdup and hashmapPut both set errno on failure.
    // Set errno to 0 so we can recognize whether anything went wrong.
    int saved_errno = errno;
    errno = 0;

    tmp_key = strdup(key);
    if (tmp_key == NULL) {
        goto clean_up;
    }

    tmp_val = strdup(value);
    if (tmp_val == NULL) {
        goto clean_up;
    }

    old_val = hashmapPut(str_parms->map, tmp_key, tmp_val);
    if (old_val == NULL) {
        // Did hashmapPut fail?
        if (errno == ENOMEM) {
            goto clean_up;
        }
        // For new keys, hashmap takes ownership of tmp_key and tmp_val.
        RELEASE_OWNERSHIP(tmp_key);
        RELEASE_OWNERSHIP(tmp_val);
        tmp_key = tmp_val = NULL;
    } else {
        // For existing keys, hashmap takes ownership of tmp_val.
        // (It also gives up ownership of old_val.)
        RELEASE_OWNERSHIP(tmp_val);
        tmp_val = NULL;
    }

clean_up:
    free(tmp_key);
    free(tmp_val);
    free(old_val);
    int result = -errno;
    errno = saved_errno;
    return result;
}

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_has_key(struct str_parms *str_parms, const char *key) {
    return hashmapGet(str_parms->map, (void *)key) != NULL;
}

int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
                      int len)
{
    // TODO: hashmapGet should take a const* key.
    char* value = static_cast<char*>(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 *end;

    // TODO: hashmapGet should take a const* key.
    char* value = static_cast<char*>(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 *end;

    // TODO: hashmapGet should take a const* key.
    char* value = static_cast<char*>(hashmapGet(str_parms->map, (void*)(key)));
    if (!value)
        return -ENOENT;

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

    *val = out;
    return 0;
}

static bool combine_strings(void *key, void *value, void *context)
{
    char** old_str = static_cast<char**>(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 UNUSED)
{
    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);
}
