/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <string.h>
#include <stdio.h>

#include "os/mynewt.h"
#include "base64/base64.h"

#include "config/config.h"
#include "config_priv.h"

struct conf_handler_head conf_handlers;

static os_event_fn conf_ev_fn_load;

static struct os_mutex conf_mtx;

/* OS event - causes persisted config values to be loaded at startup. */
static struct os_event conf_ev_load = {
    .ev_cb = conf_ev_fn_load,
};

void
conf_init(void)
{
    int rc;

    os_mutex_init(&conf_mtx);

    SLIST_INIT(&conf_handlers);
    conf_store_init();

    (void)rc;

#if MYNEWT_VAL(CONFIG_CLI)
    rc = conf_cli_register();
    SYSINIT_PANIC_ASSERT(rc == 0);
#endif
#if MYNEWT_VAL(CONFIG_NEWTMGR)
    rc = conf_nmgr_register();
    SYSINIT_PANIC_ASSERT(rc == 0);
#endif

    /* Delay loading the configuration until the default event queue is
     * processed.  This gives main() a chance to configure the underlying
     * storage first.
     */
    os_eventq_put(os_eventq_dflt_get(), &conf_ev_load);
}

void
conf_lock(void)
{
    os_mutex_pend(&conf_mtx, 0xFFFFFFFF);
}

void
conf_unlock(void)
{
    os_mutex_release(&conf_mtx);
}

int
conf_register(struct conf_handler *handler)
{
    conf_lock();
    SLIST_INSERT_HEAD(&conf_handlers, handler, ch_list);
    conf_unlock();
    return 0;
}

static void
conf_ev_fn_load(struct os_event *ev)
{
    conf_ensure_loaded();
}

/*
 * Find conf_handler based on name.
 */
struct conf_handler *
conf_handler_lookup(char *name)
{
    struct conf_handler *ch;

    SLIST_FOREACH(ch, &conf_handlers, ch_list) {
        if (!strcmp(name, ch->ch_name)) {
            return ch;
        }
    }
    return NULL;
}

/*
 * Separate string into argv array.
 */
int
conf_parse_name(char *name, int *name_argc, char *name_argv[])
{
    char *tok;
    char *tok_ptr;
    char *sep = CONF_NAME_SEPARATOR;
    int i;

    tok = strtok_r(name, sep, &tok_ptr);

    i = 0;
    while (tok) {
        name_argv[i++] = tok;
        tok = strtok_r(NULL, sep, &tok_ptr);
    }
    *name_argc = i;

    return 0;
}

struct conf_handler *
conf_parse_and_lookup(char *name, int *name_argc, char *name_argv[])
{
    int rc;

    rc = conf_parse_name(name, name_argc, name_argv);
    if (rc) {
        return NULL;
    }
    return conf_handler_lookup(name_argv[0]);
}

int
conf_value_from_str(char *val_str, enum conf_type type, void *vp, int maxlen)
{
    int32_t val;
    int64_t val64;
    char *eptr;

    if (!val_str) {
        goto err;
    }
    switch (type) {
    case CONF_INT8:
    case CONF_INT16:
    case CONF_INT32:
    case CONF_BOOL:
        val = strtol(val_str, &eptr, 0);
        if (*eptr != '\0') {
            goto err;
        }
        if (type == CONF_BOOL) {
            if (val < 0 || val > 1) {
                goto err;
            }
            *(bool *)vp = val;
        } else if (type == CONF_INT8) {
            if (val < INT8_MIN || val > UINT8_MAX) {
                goto err;
            }
            *(int8_t *)vp = val;
        } else if (type == CONF_INT16) {
            if (val < INT16_MIN || val > UINT16_MAX) {
                goto err;
            }
            *(int16_t *)vp = val;
        } else if (type == CONF_INT32) {
            *(int32_t *)vp = val;
        }
        break;
    case CONF_INT64:
        val64 = strtoll(val_str, &eptr, 0);
        if (*eptr != '\0') {
            goto err;
        }
        *(int64_t *)vp = val64;
        break;
    case CONF_STRING:
        val = strlen(val_str);
        if (val + 1 > maxlen) {
            goto err;
        }
        strcpy(vp, val_str);
        break;
    default:
        goto err;
    }
    return 0;
err:
    return OS_INVALID_PARM;
}

int
conf_bytes_from_str(char *val_str, void *vp, int *len)
{
    int tmp;

    if (base64_decode_len(val_str) > *len) {
        return OS_INVALID_PARM;
    }
    tmp = base64_decode(val_str, vp);
    if (tmp < 0) {
        return OS_INVALID_PARM;
    }
    *len = tmp;
    return 0;
}

char *
conf_str_from_value(enum conf_type type, void *vp, char *buf, int buf_len)
{
    int32_t val;

    if (type == CONF_STRING) {
        return vp;
    }
    switch (type) {
    case CONF_INT8:
    case CONF_INT16:
    case CONF_INT32:
    case CONF_BOOL:
        if (type == CONF_BOOL) {
            val = *(bool *)vp;
        } else if (type == CONF_INT8) {
            val = *(int8_t *)vp;
        } else if (type == CONF_INT16) {
            val = *(int16_t *)vp;
        } else {
            val = *(int32_t *)vp;
        }
        snprintf(buf, buf_len, "%ld", (long)val);
        return buf;
    case CONF_INT64:
        snprintf(buf, buf_len, "%lld", *(long long *)vp);
        return buf;
    default:
        return NULL;
    }
}

char *
conf_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len)
{
    if (BASE64_ENCODE_SIZE(vp_len) > buf_len) {
        return NULL;
    }
    base64_encode(vp, vp_len, buf, 1);
    return buf;
}

int
conf_set_value(char *name, char *val_str)
{
    int name_argc;
    char *name_argv[CONF_MAX_DIR_DEPTH];
    struct conf_handler *ch;
    int rc;

    conf_lock();
    ch = conf_parse_and_lookup(name, &name_argc, name_argv);
    if (!ch) {
        rc = OS_INVALID_PARM;
        goto out;
    }
    rc = ch->ch_set(name_argc - 1, &name_argv[1], val_str);
out:
    conf_unlock();
    return rc;
}

/*
 * Get value in printable string form. If value is not string, the value
 * will be filled in *buf.
 * Return value will be pointer to beginning of that buffer,
 * except for string it will pointer to beginning of string.
 */
char *
conf_get_value(char *name, char *buf, int buf_len)
{
    int name_argc;
    char *name_argv[CONF_MAX_DIR_DEPTH];
    struct conf_handler *ch;
    char *rval = NULL;

    conf_lock();
    ch = conf_parse_and_lookup(name, &name_argc, name_argv);
    if (!ch) {
        goto out;
    }

    if (!ch->ch_get) {
        goto out;
    }
    rval = ch->ch_get(name_argc - 1, &name_argv[1], buf, buf_len);
out:
    conf_unlock();
    return rval;
}

int
conf_commit(char *name)
{
    int name_argc;
    char *name_argv[CONF_MAX_DIR_DEPTH];
    struct conf_handler *ch;
    int rc;
    int rc2;

    conf_lock();
    if (name) {
        ch = conf_parse_and_lookup(name, &name_argc, name_argv);
        if (!ch) {
            rc = OS_INVALID_PARM;
            goto out;
        }
        if (ch->ch_commit) {
            rc = ch->ch_commit();
        } else {
            rc = 0;
        }
    } else {
        rc = 0;
        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
            if (ch->ch_commit) {
                rc2 = ch->ch_commit();
                if (!rc) {
                    rc = rc2;
                }
            }
        }
    }
out:
    conf_unlock();
    return rc;
}
