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

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