/*
 * Copyright (C) 2020-2020 ikonke
 */



#include "kk_dm_api.h"
#include "kk_tsl_common.h"
#include "kk_dm_mng.h"


static dm_api_ctx_t g_dm_api_ctx;

static dm_api_ctx_t *_dm_api_get_ctx(void)
{
    return &g_dm_api_ctx;
}

static void _dm_api_lock(void)
{
    dm_api_ctx_t *ctx = _dm_api_get_ctx();
    if (ctx->mutex) {
        HAL_MutexLock(ctx->mutex);
    }
}

static void _dm_api_unlock(void)
{
    dm_api_ctx_t *ctx = _dm_api_get_ctx();
    if (ctx->mutex) {
        HAL_MutexUnlock(ctx->mutex);
    }
}


int iotx_dm_post_property(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len)
{
    int res = 0;

    _dm_api_lock();

    res = dm_mgr_upstream_thing_property_post(devid, payload, payload_len);
    if (res < SUCCESS_RETURN) {
        _dm_api_unlock();
        return FAIL_RETURN;
    }

    _dm_api_unlock();
    return res;
}


int iotx_dm_subdev_create(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                          _IN_ char device_name[DEVICE_NAME_MAXLEN],
                          _IN_ char device_secret[DEVICE_SECRET_MAXLEN], _OU_ int *devid)
{
    int res = 0;

    if (product_key == NULL || device_name == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        devid == NULL) {
        return INVALID_PARAMETER;
    }

    if (device_secret != NULL && strlen(device_secret) >= DEVICE_SECRET_MAXLEN) {
        return INVALID_PARAMETER;
    }

    _dm_api_lock();
    res = dm_mgr_device_create(IOTX_DM_DEVICE_SUBDEV, product_key, device_name, device_secret, devid);
    if (res != SUCCESS_RETURN) {
        _dm_api_unlock();
        return FAIL_RETURN;
    }
    _dm_api_unlock();
    return SUCCESS_RETURN;
}


int kk_dm_subdev_register(_IN_ int devid)
{
    int res = 0;
    dm_mgr_dev_node_t *search_node = NULL;

    if (devid < 0) {
        return INVALID_PARAMETER;
    }

    _dm_api_lock();
    res = dm_mgr_search_dev_by_devid(devid, (void **)&search_node);
    if (res != SUCCESS_RETURN) {
        _dm_api_unlock();
        return FAIL_RETURN;
    }

    if ((strlen(search_node->device_secret) > 0) && (strlen(search_node->device_secret) < DEVICE_SECRET_MAXLEN)) {
        _dm_api_unlock();
        return SUCCESS_RETURN;
    }

    res = dm_mgr_upstream_thing_sub_register(devid);

    _dm_api_unlock();
    return res;
}

int kk_dm_subdev_unregister(_IN_ int devid)
{
    int res = 0;

    if (devid < 0) {
        return INVALID_PARAMETER;
    }

    _dm_api_lock();

    res = dm_mgr_upstream_thing_sub_unregister(devid);

    _dm_api_unlock();
    return res;
}

int kk_dm_subdev_topo_add(_IN_ int devid)
{
    int res = 0;

    if (devid < 0) {
        return INVALID_PARAMETER;
    }

    _dm_api_lock();

    res = dm_mgr_upstream_thing_topo_add(devid);

    _dm_api_unlock();
    return res;
}

int iotx_dm_subdev_topo_del(_IN_ int devid)
{
    int res = 0;

    if (devid < 0) {
        return DM_INVALID_PARAMETER;
    }

    _dm_api_lock();

    res = dm_mgr_upstream_thing_topo_delete(devid);

    _dm_api_unlock();
    return res;
}

int iotx_dm_subdev_login(_IN_ int devid)
{
    int res = 0;

    if (devid < 0) {
        return INVALID_PARAMETER;
    }

    _dm_api_lock();

    res = dm_mgr_upstream_combine_login(devid);

    _dm_api_unlock();
    return res;
}

int iotx_dm_subdev_logout(_IN_ int devid)
{
    int res = 0;

    if (devid < 0) {
        return DM_INVALID_PARAMETER;
    }

    _dm_api_lock();

    res = dm_mgr_upstream_combine_logout(devid);

    _dm_api_unlock();
    return res;
}


void iotx_dm_dispatch(void)
{
    int count = 0;
    void *data = NULL;
    dm_api_ctx_t *ctx = _dm_api_get_ctx();

#if defined(OTA_ENABLED) && !defined(BUILD_AOS)
    dm_cota_status_check();
    dm_fota_status_check();
#endif
    while (CONFIG_DISPATCH_QUEUE_MAXLEN == 0 || count++ < CONFIG_DISPATCH_QUEUE_MAXLEN) {
        //printf("iotx_dm_dispatch time=%d \n", HAL_UptimeMs());
        if (dm_queue_msg_next(&data) == SUCCESS_RETURN) {
            //dm_queue_msg_t *msg = (dm_queue_msg_t *)data;
            printf("dm_queue_msg_next call \n");
            if (ctx->event_callback) {
                ctx->event_callback(1, data);
            }

            
            free(data);
            data = NULL;
        } else {
            break;
        }
    }
}

int iotx_dm_connect(_IN_ iotx_dm_event_callback cb)
{
    int res = 0;
    dm_api_ctx_t *ctx = _dm_api_get_ctx();

    if (cb == NULL) {
        return INVALID_PARAMETER;
    }

    /* DM Event Callback */

    ctx->event_callback = cb;


    /*res = dm_client_connect(IOTX_DM_CLIENT_CONNECT_TIMEOUT_MS);
    if (res != SUCCESS_RETURN) {
        return FAIL_RETURN;
    }

#ifdef ALCS_ENABLED

    res = dm_server_connect();
    if (res != SUCCESS_RETURN) {
        return FAIL_RETURN;
    }
#endif*/

    return SUCCESS_RETURN;
}


