#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include "vn_client.h"

#define DIE_IF_FAILED(error_msg, r)                                     \
do                                                                      \
{                                                                       \
    assert(r);                                                          \
    if (r->error_code)                                                  \
    {                                                                   \
        fprintf(stderr, "%s: %d : %s\n", error_msg, r->error_code, r->error_string); \
        exit(1);                                                        \
    }                                                                   \
} while (0)

int main(int argc, char *argv[])
{

    do
    {
        vn_client_config_t cfg = {};
        strcpy(cfg.remote_host, "192.168.0.197");
        cfg.timeout = 15;
    
        vn_asynch_result_t *ar;
        vn_result_t *r;

        printf("Started\n");
        
        vn_client_context_t *ctx = vn_client_create(&cfg);
    
        // Loging in
        ar = vn_client_login(ctx, "admin", "topse");
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Login failed", r);
        printf("Defualt role: %d\n", *((int*)r->kvl[0]->value));
        vn_asynch_result_destroy(ar);

        // Getting roles
        ar = vn_client_get_roles(ctx);
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Get roles failed", r);
        // iterate over roles and print them out
        // printf("Roles:\n");
        // for (vn_kv_t **p = r->kvl; *p != 0; ++p)
        // {
        //     vn_kv_t *role = *p;
        //     printf("%d -> %s\n", *(unsigned*)(role->key), (char*)role->value);
        // }
        vn_asynch_result_destroy(ar);

        // Getting sets
        ar = vn_client_get_sets(ctx, -1);
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Get sets failed", r);
        // iterate over sets and print them out
        // printf("Sets:\n");
        // for (vn_kv_t **p = r->kvl; *p != 0; ++p)
        // {
        //     vn_kv_t *set = *p;
        //     printf("%d -> %s\n", *(unsigned*)(set->key), (char*)set->value);
        // }
        vn_asynch_result_destroy(ar);


        // Getting objects
        ar = vn_client_get_objects(ctx, -1);
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Get objects failed", r);

        // iterate over objects and print them out
        for (vn_kv_t **p = r->kvl; *p != 0; ++p)
        {
            vn_kv_t *obj = *p;
            printf("DEVICE %d\n", *(unsigned*)(obj->key));
            // iterate over attributes
            vn_kv_t **attrs = (vn_kv_t **)obj->value;
            for (vn_kv_t **a = attrs; *a != 0; ++a)
            {
                printf("%s:%s\n", (char*)(*a)->key, (char*)(*a)->value);
            }
            
            printf("-------------\n");
        }
        vn_asynch_result_destroy(ar);

        // Getting events
        ar = vn_client_get_events(ctx, 10, -1);
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Get events failed", r);
        // iterate over events and print them out
        // for (vn_kv_t **p = r->kvl; *p != 0; ++p)
        // {
        //     vn_kv_t *obj = *p;
        //     printf("EVENT %d\n", *(unsigned*)(obj->key));
        //     // iterate over attributes
        //     vn_kv_t **attrs = (vn_kv_t **)obj->value;
        //     for (vn_kv_t **a = attrs; *a != 0; ++a)
        //     {
        //         printf("%s:%s\n", (char*)(*a)->key, (char*)(*a)->value);
        //     }
            
        //     printf("-------------\n");
        // }
        vn_asynch_result_destroy(ar);

        // Getting media URL
        ar = vn_client_get_media_url(ctx, 127, 0, 0, 0, NULL, NULL, 0);
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Get media URL failed", r);

//        printf("URL: %s\n", (char*)r->kvl[0]->value);
        vn_asynch_result_destroy(ar);


        // Getting snapshot
        ar = vn_client_get_snapshot(ctx, 127, 0, 1, 0);
        r = vn_asynch_result_get(ar, 15000);
        DIE_IF_FAILED("Get snapshot failed", r);
        
        FILE *fh = fopen("/tmp/snapshot.jpg", "w");
        fwrite(r->kvl[0]->value, *((unsigned*)r->kvl[0]->key), 1, fh);
        fclose(fh);

        vn_asynch_result_destroy(ar);


        vn_client_destroy(ctx);


        sleep(3);
    } while (1);

    return 0;
}
