#ifndef VN_CLIENT_H
#define VN_CLIENT_H

#include "vn_os.h"
#include "vn_asynch_result.h"

#include <time.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef void vn_client_context_t;
    
#pragma pack(push, 1) /* store previous pack value */
                      /* and set new value to 1 (no alignment) */

struct vn_client_config_t
{
    /** 
     * Remote host name
     */
    char remote_host[128];

    /** 
     * Remote port
     */
    unsigned remote_port;

    /** 
     * Use SSL (0/1)
     */    
    int use_ssl;

    /**
     * Maximum time in seconds for network syscals
     */
    int timeout;
};
    
#pragma pack(pop)     /* restore previous pack value */

VN_SDK_API vn_client_context_t *vn_client_create(vn_client_config_t *cfg);


/** 
 * Login to remote host
 * 
 * @param cfg [in]
 * @param user_name [in] 
 * @param password [in]
 * 
 * @return pointer to vn_asynch_result_t. Caller should call vn_asynch_result_destroy(vn_asynch_result_t *) when done
 */
VN_SDK_API vn_asynch_result_t *vn_client_login(vn_client_context_t *ctx, const char *user_name, const char *password);

/** 
 * Set auth bypassing login
 * 
 * @param cfg [in]
 * @param php_sess_id [in] 
 * @param csrf_token [in]
 */
VN_SDK_API void vn_client_set_auth(const char *php_sess_id, const char *csrf_token);


/** 
 * Get objects belong to 
 * 
 * @param ctx [in]
 * @param set_id [in] "Set" ID. If set_id is null then all objects of the system will be returned
 * @param pool_full [in/out] Return w/o performing request and set this param to true if curl pool is full and param is not NULL
 * 
 * @return vn_result_t::kvl will contain list of [OBJID]->[VALUES_MAP] where VALUES_MAP is also pointer to vn_kv_t struct
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_objects(vn_client_context_t *ctx, const char* set_id, bool* pool_full);

/**
 * Get resource tree
 *
 * @param ctx [in]
 * @param role_id [in] "Role" ID. If role_id is null then all resource tree of the system will be returned
 *
 * @return vn_result_t::kvl will contain list of [ROLE_ID]->[VALUES_MAP] where VALUES_MAP is also pointer to vn_kv_t struct
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_resource_tree(vn_client_context_t *ctx, const char* role_id = NULL);

/** 
 * Get user roles
 * 
 * @param ctx [in]
 * 
 * @return vn_result_t::kvl will contain list of [ROLE_ID]->[NAME] (unsigned->char*) values
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_roles(vn_client_context_t *ctx);

/** 
 * Get user sets belong to role
 * 
 * @param result [out] Result status of call
 * @param ctx [in]
 * @param role_id [in] Role ID. If role_id is null then all sets of the system will be returned
 * 
 * @return vn_result_t::kvl will contain list of [SET_ID]->[NAME] (unsigned->char*) values
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_sets(vn_client_context_t *ctx, const char* role_id = NULL);


/** 
 * Get media URL 
 *  
 * @param ctx [in]
 * @param video_obj_id 
 * @param audio_obj_id Can be 0
 * @param start Archive start time (UTC timestamp) or 0 (live)
 * @param end   Archive end time (UTC timestamp) or 0 (live)
 * @param transcode Transcode to different media format. Only "h264" currently supported.
 * @param resolution If transcoding enabled set frame dimensions in form "WxH", ex: "320x240"
 * @param analytics
 * @param isLocal return url for local streaming if true
 *
 * @return vn_result_t::kvl::value will contain URL (pointer to char*)
 */
VN_SDK_API vn_asynch_result_t  *vn_client_get_media_url(vn_client_context_t *ctx, const char* video_obj_id, const char* audio_obj_id, 
                                                       time_t start, time_t end, const char *transcode, const char *resolution,
                                                       int analytics, bool isLocal=false);


/** 
 * Get JPEG still image for selected device
 * 
 * @param ctx  [in]
 * @param video_obj_id Video object ID
 * @param start Archive start time (UTC timestamp) or 0 for live
 * @param stream_num Number of stream (0-LOWRES,1-NORMRES, ..)
 * @param metadata Include metadata to the JPEG
 * 
 * @return vn_result_t::kvl::key will contain size of JPEG image in bytes, vn_result_t::kvl::value will point to JPEG data
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_snapshot(vn_client_context_t *ctx, const char* video_obj_id, time_t ts, unsigned stream_num, int metadata);

    
/**
 * Get JPEG still image for selected device
 * 
 * @param ctx  [in]
 * @param obj_id Object ID
 * @param attrs [in] NULL-terminated list of key/value pairs
 * 
 * @return only error codes
 */
VN_SDK_API vn_asynch_result_t *vn_client_set_object_attrs(vn_client_context_t *ctx, const char* obj_id, const vn_kv_t **attrs);


/** 
 * Get events from eventlog
 * 
 * @param ctx  [in]
 * @param role_id
 * @param filter
 *
 * @return vn_result_t::kvl will contain list of [EVENTID]->[VALUES_MAP] where VALUES_MAP is also pointer to vn_kv_t struct
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_events(vn_client_context_t *ctx, const char* role_id, const char* filter);

/** 
 * do-action to elog
 *
 * 
 * @param ctx  [in]
 * @param event_id [in]
 * @param action [in]
 * @param role_id [in]
 * @param post_data post data in json format
 *
 * @return only error codes
 */
vn_asynch_result_t *vn_client_submit_action(vn_client_context_t *ctx, int event_id, const char* action, const char* role_id, const char* postData);

/** 
 * Destroy and free all resources
 * @param ctx [in]
 */
VN_SDK_API void vn_client_destroy(vn_client_context_t *ctx);

/**
 * Add or check an object presence
 *
 * @param ctx [in]
 * @param attrs [in] NULL-terminated list of key/value pairs
 *
 * @return vn_result_t::kvl::value will contain integer Object ID
 */
VN_SDK_API vn_asynch_result_t *vn_client_add_object(vn_client_context_t *ctx,
                                                   const vn_kv_t **attrs);

/**
 * Performs ptz command
 *
 * @param ctx [in]
 * @param objid Object ID
 * @param mode PTZ mode
 * @param cmd command in verbal form "left|right|up|down|downleft|upright|downright|upleft|in|out"
 *
 * @return only error codes
 */
VN_SDK_API vn_asynch_result_t *vn_client_perform_ptz_command(vn_client_context_t *ctx,
                                                            const char* objid,
                                                            const char *mode,
                                                            const char *cmd);

// FIXME: The following method has been deprecated.
// Please use vn_client_add_object() instead
VN_SDK_API vn_asynch_result_t *vn_client_register_device(vn_client_context_t *ctx,
                                                        const char *hwid,
                                                        const char *name,
                                                        const char *telnum,
                                                        const char *mediaFormat);

/**
 * Get position belong to Objects IDs from obj_ids array of length len
 *
 * @param ctx [in]
 * @param obj_ids [in] array of Objects IDs.
 * @param len [in] array length. If zero then positions of all dynamic objects of the system will be returned
 *
 * @return vn_result_t::kvl will contain list of [OBJID]->[POSITION JSON]
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_geo(vn_client_context_t *ctx, const char* obj_ids[], unsigned len);

/**
 * Get users
 *
 * @param ctx [in]
 *
 * @return vn_result_t::kvl will contain list of [USER_ID]->[NAME] (unsigned->char*) values
 */
VN_SDK_API vn_asynch_result_t *vn_client_get_users(vn_client_context_t *ctx);

 /**
  * Get server information (version, ...)
  *
  * @param result [out] Result status of call
  * @param ctx [in]
  *
  * @return vn_result_t::kvl will contain list of NULL terminated list of [key]->[value] or NULL if none
  * Caller should call vn_asynch_result_destroy(vn_asynch_result_t *) when done
  */
VN_SDK_API vn_asynch_result_t *vn_client_get_server_info(vn_client_context_t *ctx);



#ifdef __cplusplus
}
#endif

#endif /*VN_PLAYER_H*/
