#ifndef __KK_TSL_COM__
#define __KK_TSL_COM__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#ifndef _IN_
    #define _IN_
#endif

#ifndef _OU_
    #define _OU_
#endif
//typedef unsigned long int   uint64_t;

#define PRODUCT_TYPE_MAXLEN          (32 + 1)
#define PRODUCT_CODE_MAXLEN         (32 + 1)
#define DEVICE_CODE_MAXLEN          (32 + 1)

#define DEVICE_MAC_MAXLEN           (16 + 1)
#define DEVICE_SN_MAXLEN            (32 + 1)
#define DEVICE_VERSION_MAXLEN       (32 + 1)

#define DM_UTILS_UINT16_STRLEN (5)
#define DM_UTILS_UINT32_STRLEN (10)
#define DM_UTILS_UINT64_STRLEN (20)
#define DEVICE_PROPERTY_NAME_MAX    (64+1)
#define DEVICE_PROPERTY_VALUE_MAX    (64+1)
#define DEVICE_PROPERTY_NUM_MAX    (16)

#define KK_TSL_KEY_SCHEMA                     "schema"
#define KK_TSL_KEY_LINK                       "link"
#define KK_TSL_KEY_PRODUCTTYPE                "productType"
#define KK_TSL_KEY_PROFILE                    "profile"
#define KK_TSL_KEY_PROPERTIES                 "properties"
#define KK_TSL_KEY_EVENTS                     "events"
#define KK_TSL_KEY_SERVICES                   "services"
#define KK_TSL_KEY_PROFILE_PK                 "productKey"
#define KK_TSL_KEY_PROFILE_DN                 "deviceName"
#define KK_TSL_KEY_IDENTIFIER                 "identifier"
#define KK_TSL_KEY_NAME                       "name"
#define KK_TSL_KEY_DESC                       "desc"
#define KK_TSL_KEY_ACCESS_MODE                "accessMode"
#define KK_TSL_KEY_REQUIRED                   "required"
#define KK_TSL_KEY_METHOD                     "method"
#define KK_TSL_KEY_CALLTYPE                   "callType"
#define KK_TSL_KEY_OUTPUTDATA                 "outputData"
#define KK_TSL_KEY_INPUTDATA                  "inputData"
#define KK_TSL_KEY_DATATYPE                   "dataType"
#define KK_TSL_KEY_TYPE                       "type"
#define KK_TSL_KEY_SPECS                      "specs"
#define KK_TSL_KEY_UNIT                       "unit"
#define KK_TSL_KEY_UNITNAME                   "unitName"
#define KK_TSL_KEY_MIN                        "min"
#define KK_TSL_KEY_MAX                        "max"
#define KK_TSL_KEY_LENGTH                     "length"
#define KK_TSL_KEY_SIZE                       "size"
#define KK_TSL_KEY_ITEM                       "item"
#define KK_TSL_KEY_HEARTBEAT                  "heartbeat"
#define KK_TSL_KEY_SLEEPTIME                  "sleepTime"

#define KK_MSG_KEY_DELIMITER                  '.'
#define KK_URI_SERVICE_DELIMITER '/'
#define KK_URI_OFFSET 0

//Special Service And Event
#define KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER "set"
#define KK_TSL_SPECIAL_SERVICE_SET_METHOD     "thing.service.property.set"
#define KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER "get"
#define KK_TSL_SPECIAL_SERVICE_GET_METHOD     "thing.service.property.get"
#define KK_TSL_SPECIAL_EVENT_POST_IDENTIFIER  "post"
#define KK_TSL_SPECIAL_EVENT_POST_METHOD      "thing.event.property.post"

#define KK_TSL_VERSION_IDENTIFIER                  "Version"
#define KK_TSL_CCU_LANIP_IDENTIFIER      	       "LanIPAddress"
#define KK_TSL_CCU_WANIP_IDENTIFIER      	       "WanIPAddress"
#define KK_TSL_CCU_WANSTATE_IDENTIFIER  		   "WanState"
#define KK_TSL_CCU_IOTCLOUD_IDENTIFIER  		   "IOTCloudState"
#define KK_TSL_CCU_ARMINGSTATE_IDENTIFIER		   "ArmingState"

#define KK_TSL_GATAWAY_VERSION_IDENTIFIER      "Version"
#define KK_TSL_GATAWAY_IP_IDENTIFIER      	   "IPAddress"
#define KK_TSL_GATAWAY_MAC_IDENTIFIER      	   "MACAddress"
#define KK_TSL_GATAWAY_PORT_IDENTIFIER         "Port"
#define KK_TSL_GATAWAY_SN_IDENTIFIER      	   "SN"
#define KK_TSL_GATAWAY_WHITELIST_IDENTIFIER      	   "WhiteListState"

#define DEFAULT_HEARTBEAT_TIMEOUT      (60*1)// ten minutes

typedef enum {
    KK_DEV_ONLINE = 0,
    KK_DEV_OFFLINE,
    KK_DEV_UNKNOW,
} kk_dev_status_e;

typedef enum {
    KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA,
    KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA
} kk_tsl_data_target_e;

typedef enum {
	DEVICE_HEARTBEAT_TIMEOUT = -15,
	TSL_ALREADY_EXIST      = -14,	
    TSL_SERVICE_GET_FAILED = -13,
    TSL_SERVICE_SET_FAILED = -12,
    TSL_EVENT_GET_FAILED = -11,
    TSL_EVENT_SET_FAILED = -10,
    TSL_PROPERTY_GET_FAILED = -9,
    TSL_PROPERTY_SET_FAILED = -8,
    TSL_EVENT_NOT_EXIST = -7,
    TSL_PROPERTY_NOT_EXIST = -6,
    TSL_SERVICE_NOT_EXIST = -5,
    JSON_PARSE_FAILED = -4,
    MEMORY_NOT_ENOUGH = -3,
    INVALID_PARAMETER = -2,
    FAIL_RETURN = -1,
    SUCCESS_RETURN = 0,
} kk_tsl_error_code_t;

typedef enum {
	KK_TSL_DATA_TYPE_NONE,                    //none
	KK_TSL_DATA_TYPE_INT,                     //int
	KK_TSL_DATA_TYPE_FLOAT,                   //float
	KK_TSL_DATA_TYPE_DOUBLE,                  //double
	KK_TSL_DATA_TYPE_TEXT,                    //string
	KK_TSL_DATA_TYPE_ENUM,                    //int
	KK_TSL_DATA_TYPE_DATE,                    //string
	KK_TSL_DATA_TYPE_BOOL,                    //bool,0 or 1
	KK_TSL_DATA_TYPE_ARRAY,                   //support int, float, double, text
	KK_TSL_DATA_TYPE_STRUCT,                  //support above 8 data types
} kk_tsl_data_type_e;
typedef struct {
	kk_tsl_data_type_e type;
	int size;
	void *value;
} kk_tsl_data_value_complex_t;

typedef struct {
	kk_tsl_data_type_e type;
	int mix;
	int max;
	int length;
	union {
		int value_int;
		float value_float;
		double value_double;
		void *value;							 //string or complex type accroding to data type
	};
} kk_tsl_data_value_t;


typedef struct {
	char *identifier;
	char *accessMode;
	kk_tsl_data_value_t data_value;
} kk_tsl_data_t;

typedef struct {
    char *identifier;
    int input_data_number;                       //input_data Number
    kk_tsl_data_t *input_datas;               //input_data array, type is dm_shw_data_t
    int output_data_number;                      //ouput_data Number
    kk_tsl_data_t *output_datas;              //output_data array, type is dm_shw_data_t
} kk_tsl_event_t;

typedef struct {
	char *identifier;                            //synchronized or asynchronized
	int input_data_number;                       //input_data_number
    kk_tsl_data_t *input_datas;               //input_data array, type is dm_shw_data_t
    int output_data_number;                      //ouput_data Number
    kk_tsl_data_t *output_datas;              //output_data array, type is dm_shw_data_t
} kk_tsl_service_t;


typedef struct {
	int property_number;
	kk_tsl_data_t *properties;                //property array, type is dm_shw_data_t
	int event_number;
	kk_tsl_event_t *events;                   //event array, type is dm_shw_event_t
	int service_number;
	kk_tsl_service_t *services;               //service array, type is dm_shw_service_t
} kk_tsl_t;
void kk_tsl_datavalue_free(kk_tsl_data_value_t *data_value);
int kk_tsl_get_property_value_ex(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void *value);
int kk_tsl_get_event_oput_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value);
int kk_tsl_get_service_input_output_value(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key,
        _IN_ int key_len, _IN_ void *value);
#endif
