/*
 * 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/memory.h>
#include <cutils/str_parms.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;
    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;
}

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

static bool remove_pair(void *key, void *value, void *context)
{
    struct remove_ctxt *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, 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)
{
    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 -EINVAL;

    *val = out;
    return 0;
}

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