c6c09bcc60fe5e29f2cfc32020aefb671f577d81
[apps/native/telegram-tizen.git] / tg-engine-service / tg_engine / tg_engine.c
1 /**
2  * @file tg_engine.c
3  * @author sandeep
4  * @date Jun 24, 2015
5  */
6
7 #include "tg_engine.h"
8 #include "server_response.h"
9 #include <pthread.h>
10 #include <Ecore.h>
11 #include "tg_db_wrapper.h"
12 #include "tgl-fetch.h"
13 #include <mime_type.h>
14 #include "device_contacts_manager.h"
15 #include "tg-engine-service.h"
16
17 #define DC_SERIALIZED_MAGIC 0x868aa81d
18 #define STATE_FILE_MAGIC 0x28949a93
19 #define SECRET_CHAT_FILE_MAGIC 0x37a1988a
20
21 static struct _tg_engine {
22         int verbosity;
23         int msg_num_mode;
24         char *default_username;
25         char *config_filename;
26         char *prefix;
27         char *auth_file_name;
28         char *state_file_name;
29         char *secret_chat_file_name;
30         char *downloads_directory;
31         char *config_directory;
32         char *binlog_file_name;
33         char *lua_file;
34         int binlog_enabled;
35         int log_level;
36         int sync_from_start;
37         int allow_weak_random;
38         int disable_colors;
39         int readline_disabled;
40         int disable_output;
41         int reset_authorization;
42         int port;
43         int use_ids;
44         int ipv6_enabled;
45         char *start_command;
46         char *rsa_file_name;
47         char *config_full_path;
48         int need_dc_list_update;
49         struct tgl_state *TLS;
50 } s_info;
51
52 static void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
53 static void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
54 static void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
55 static void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
56 static void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
57 static void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
58 extern void delete_all_messages_from_chat(int buddy_id, int type_of_chat);
59 void tgl_engine_var_init(void)
60 {
61         s_info.default_username = NULL;
62         s_info.config_filename = NULL;
63         s_info.auth_file_name = NULL;
64         s_info.state_file_name = NULL;
65         s_info.secret_chat_file_name = NULL;
66         s_info.downloads_directory = NULL;
67         s_info.config_directory = NULL;
68         s_info.binlog_file_name = NULL;
69         s_info.lua_file = NULL;
70 }
71
72 void tgl_engine_var_free(void)
73 {
74         if (s_info.default_username) {
75                 free(s_info.default_username);
76                 s_info.default_username = NULL;
77         }
78         if (s_info.config_filename) {
79                 free(s_info.config_filename);
80                 s_info.config_filename = NULL;
81         }
82         if (s_info.auth_file_name) {
83                 free(s_info.auth_file_name);
84                 s_info.auth_file_name = NULL;
85         }
86         if (s_info.state_file_name) {
87                 free(s_info.state_file_name);
88                 s_info.state_file_name = NULL;
89         }
90         if (s_info.secret_chat_file_name) {
91                 free(s_info.secret_chat_file_name);
92                 s_info.secret_chat_file_name = NULL;
93         }
94         if (s_info.downloads_directory) {
95                 free(s_info.downloads_directory);
96                 s_info.downloads_directory = NULL;
97         }
98         if (s_info.config_directory) {
99                 free(s_info.config_directory);
100                 s_info.config_directory = NULL;
101         }
102         if (s_info.binlog_file_name) {
103                 free(s_info.binlog_file_name);
104                 s_info.binlog_file_name = NULL;
105         }
106         if (s_info.lua_file) {
107                 free(s_info.lua_file);
108                 s_info.lua_file = NULL;
109         }
110         if (s_info.TLS) {
111                 tgl_state_free(s_info.TLS);
112                 tgl_free_all(s_info.TLS);
113                 s_info.TLS = NULL;
114         }
115 }
116
117 char *tgl_engine_get_auth_key_filename(void)
118 {
119   return s_info.auth_file_name;
120 }
121
122 char *tgl_engine_get_state_filename(void)
123 {
124   return s_info.state_file_name;
125 }
126
127 char *tgl_engine_get_secret_chat_filename (void)
128 {
129   return s_info.secret_chat_file_name;
130 }
131
132 char *tgl_engine_get_downloads_directory (void)
133 {
134   return s_info.downloads_directory;
135 }
136
137 void write_dc(struct tgl_dc *DC, void *extra)
138 {
139         int auth_file_fd = *(int *)extra;
140         int x;
141
142         x = !!DC;
143
144         if (!x) {
145                 assert(write(auth_file_fd, &x, 4) == 4);
146                 return;
147         }
148
149         assert(write(auth_file_fd, &x, 4) == 4);
150         assert(DC->has_auth);
151         assert(write(auth_file_fd, &DC->port, 4) == 4);
152         int l = strlen(DC->ip);
153         assert(write(auth_file_fd, &l, 4) == 4);
154         assert(write(auth_file_fd, DC->ip, l) == l);
155         assert(write(auth_file_fd, &DC->auth_key_id, 8) == 8);
156         assert(write(auth_file_fd, DC->auth_key, 256) == 256);
157 }
158
159 void write_secret_chat(tgl_peer_t *_P, void *extra)
160 {
161         struct tgl_secret_chat *P = (void *)_P;
162
163         if (tgl_get_peer_type (P->id) != TGL_PEER_ENCR_CHAT) {
164                 return;
165         }
166
167         if (P->state != sc_ok) {
168                 return;
169         }
170
171         int *a = extra;
172         int fd = a[0];
173         a[1] ++;
174
175         int id = tgl_get_peer_id (P->id);
176         assert (write (fd, &id, 4) == 4);
177         //assert (write (fd, &P->flags, 4) == 4);
178         int l = strlen(P->print_name);
179         assert(write (fd, &l, 4) == 4);
180         assert(write (fd, P->print_name, l) == l);
181         assert(write (fd, &P->user_id, 4) == 4);
182         assert(write (fd, &P->admin_id, 4) == 4);
183         assert(write (fd, &P->date, 4) == 4);
184         assert(write (fd, &P->ttl, 4) == 4);
185         assert(write (fd, &P->layer, 4) == 4);
186         assert(write (fd, &P->access_hash, 8) == 8);
187         assert(write (fd, &P->state, 4) == 4);
188         assert(write (fd, &P->key_fingerprint, 8) == 8);
189         assert(write (fd, &P->key, 256) == 256);
190         assert(write (fd, &P->first_key_sha, 20) == 20);
191         assert(write (fd, &P->in_seq_no, 4) == 4);
192         assert(write (fd, &P->last_in_seq_no, 4) == 4);
193         assert(write (fd, &P->out_seq_no, 4) == 4);
194 }
195
196 void write_secret_chat_file(void)
197 {
198         if (s_info.binlog_enabled) {
199                 return;
200         }
201         int secret_chat_fd = open (tgl_engine_get_secret_chat_filename(), O_CREAT | O_RDWR, 0600);
202         assert (secret_chat_fd >= 0);
203         int x = SECRET_CHAT_FILE_MAGIC;
204         assert (write (secret_chat_fd, &x, 4) == 4);
205         x = 2;
206         assert (write (secret_chat_fd, &x, 4) == 4); // version
207         assert (write (secret_chat_fd, &x, 4) == 4); // num
208
209         int y[2];
210         y[0] = secret_chat_fd;
211         y[1] = 0;
212
213         tgl_peer_iterator_ex(s_info.TLS, write_secret_chat, y);
214
215         lseek(secret_chat_fd, 8, SEEK_SET);
216         assert(write (secret_chat_fd, &y[1], 4) == 4);
217         close(secret_chat_fd);
218 }
219
220 void write_auth_file(void)
221 {
222         if (s_info.binlog_enabled) {
223                 return;
224         }
225
226         int auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
227
228         assert(auth_file_fd >= 0);
229         int x = DC_SERIALIZED_MAGIC;
230         assert(write(auth_file_fd, &x, 4) == 4);
231         assert(write(auth_file_fd, &s_info.TLS->max_dc_num, 4) == 4);
232         assert(write(auth_file_fd, &s_info.TLS->dc_working_num, 4) == 4);
233         tgl_dc_iterator_ex(s_info.TLS, write_dc, &auth_file_fd);
234         assert(write(auth_file_fd, &s_info.TLS->our_id, 4) == 4);
235         close(auth_file_fd);
236 }
237
238 void read_dc(int auth_file_fd, int id, unsigned ver)
239 {
240         int port = 0;
241         assert(read(auth_file_fd, &port, 4) == 4);
242         int l = 0;
243         assert(read(auth_file_fd, &l, 4) == 4);
244         assert(l >= 0 && l < 100);
245         char ip[100];
246         assert(read(auth_file_fd, ip, l) == l);
247         ip[l] = 0;
248
249         long long auth_key_id;
250         static unsigned char auth_key[256];
251         assert(read(auth_file_fd, &auth_key_id, 8) == 8);
252         assert(read(auth_file_fd, auth_key, 256) == 256);
253
254         //bl_do_add_dc(id, ip, l, port, auth_key_id, auth_key);
255         bl_do_dc_option(s_info.TLS, id, 2, "DC", l, ip, port);
256         bl_do_set_auth_key_id(s_info.TLS, id, auth_key);
257         bl_do_dc_signed(s_info.TLS, id);
258 }
259
260 void empty_auth_file(void)
261 {
262         if (s_info.TLS->test_mode) {
263                 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_TEST_1), TG_SERVER_TEST_1, 443);
264                 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_TEST_2), TG_SERVER_TEST_2, 443);
265                 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_TEST_3), TG_SERVER_TEST_3, 443);
266                 bl_do_set_working_dc(s_info.TLS, 2);
267         } else {
268                 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_1), TG_SERVER_1, 443);
269                 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_2), TG_SERVER_2, 443);
270                 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_3), TG_SERVER_3, 443);
271                 bl_do_dc_option(s_info.TLS, 4, 0, "", strlen(TG_SERVER_4), TG_SERVER_4, 443);
272                 bl_do_dc_option(s_info.TLS, 5, 0, "", strlen(TG_SERVER_5), TG_SERVER_5, 443);
273                 bl_do_set_working_dc(s_info.TLS, 4);
274         }
275 }
276
277 void read_secret_chat(int fd, int v)
278 {
279         int id, l, user_id, admin_id, date, ttl, layer, state;
280         long long access_hash, key_fingerprint;
281         static char s[1000];
282         static unsigned char key[256];
283         static unsigned char sha[20];
284         assert(read(fd, &id, 4) == 4);
285         //assert(read(fd, &flags, 4) == 4);
286         assert(read(fd, &l, 4) == 4);
287         assert(l > 0 && l < 1000);
288         assert(read(fd, s, l) == l);
289         assert(read(fd, &user_id, 4) == 4);
290         assert(read(fd, &admin_id, 4) == 4);
291         assert(read(fd, &date, 4) == 4);
292         assert(read(fd, &ttl, 4) == 4);
293         assert(read(fd, &layer, 4) == 4);
294         assert(read(fd, &access_hash, 8) == 8);
295         assert(read(fd, &state, 4) == 4);
296         assert(read(fd, &key_fingerprint, 8) == 8);
297         assert(read(fd, &key, 256) == 256);
298         if (v >= 2) {
299                 assert(read(fd, sha, 20) == 20);
300         }
301         int in_seq_no = 0, out_seq_no = 0, last_in_seq_no = 0;
302         if (v >= 1) {
303                 assert(read(fd, &in_seq_no, 4) == 4);
304                 assert(read(fd, &last_in_seq_no, 4) == 4);
305                 assert(read(fd, &out_seq_no, 4) == 4);
306         }
307
308         bl_do_encr_chat_create(s_info.TLS, id, user_id, admin_id, s, l);
309         struct tgl_secret_chat  *P =(void *)tgl_peer_get(s_info.TLS, TGL_MK_ENCR_CHAT(id));
310         assert(P &&(P->flags & FLAG_CREATED));
311         bl_do_encr_chat_set_date(s_info.TLS, P, date);
312         bl_do_encr_chat_set_ttl(s_info.TLS, P, ttl);
313         bl_do_encr_chat_set_layer(s_info.TLS ,P, layer);
314         bl_do_encr_chat_set_access_hash(s_info.TLS, P, access_hash);
315         bl_do_encr_chat_set_state(s_info.TLS, P, state);
316         bl_do_encr_chat_set_key(s_info.TLS, P, key, key_fingerprint);
317         if (v >= 2) {
318                 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
319         } else {
320                 SHA1((void *)key, 256, sha);
321                 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
322         }
323         if (v >= 1) {
324                 bl_do_encr_chat_set_seq(s_info.TLS, P, in_seq_no, last_in_seq_no, out_seq_no);
325         }
326 }
327
328 void read_secret_chat_file(void)
329 {
330         if (s_info.binlog_enabled) {
331                 return;
332         }
333
334         int secret_chat_fd = open(tgl_engine_get_secret_chat_filename(), O_RDWR, 0600);
335
336         if (secret_chat_fd < 0) {
337                 return;
338         }
339         //assert(secret_chat_fd >= 0);
340         int x;
341         if (read(secret_chat_fd, &x, 4) < 4) { close(secret_chat_fd); return; }
342         if (x != SECRET_CHAT_FILE_MAGIC) { close(secret_chat_fd); return; }
343         int v = 0;
344         assert(read(secret_chat_fd, &v, 4) == 4);
345         assert(v == 0 || v == 1 || v == 2); // version
346         assert(read(secret_chat_fd, &x, 4) == 4);
347         assert(x >= 0);
348         while(x --> 0) {
349                 read_secret_chat(secret_chat_fd, v);
350         }
351         close(secret_chat_fd);
352 }
353
354 void read_state_file(void)
355 {
356         if (s_info.binlog_enabled) {
357                 return;
358         }
359         int state_file_fd = open(tgl_engine_get_state_filename(), O_CREAT | O_RDWR, 0600);
360         if (state_file_fd < 0)
361                 return;
362
363         int version, magic;
364
365         if (read(state_file_fd, &magic, 4) < 4) {
366                 close(state_file_fd);
367                 return;
368         }
369
370         if (magic !=(int)STATE_FILE_MAGIC) {
371                 close(state_file_fd);
372                 return;
373         }
374
375         if (read(state_file_fd, &version, 4) < 4) {
376                 close(state_file_fd);
377                 return;
378         }
379
380         assert(version >= 0);
381         int x[4];
382
383         if (read(state_file_fd, x, 16) < 16) {
384                 close(state_file_fd);
385                 return;
386         }
387
388         int pts = x[0];
389         int qts = x[1];
390         int seq = x[2];
391         int date = x[3];
392         close(state_file_fd);
393         bl_do_set_seq(s_info.TLS, seq);
394         bl_do_set_pts(s_info.TLS, pts);
395         bl_do_set_qts(s_info.TLS, qts);
396         bl_do_set_date(s_info.TLS, date);
397 }
398
399 void read_auth_file(void)
400 {
401         if (s_info.binlog_enabled) {
402                 return;
403         }
404         int auth_file_fd;
405
406         auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
407         if (auth_file_fd < 0) {
408                 /**
409                  * Logging this for handling exceptional cases.
410                  */
411                 empty_auth_file();
412                 return;
413         }
414
415         assert(auth_file_fd >= 0);
416         unsigned x;
417         unsigned m;
418
419         if (read(auth_file_fd, &m, 4) < 4 ||(m != DC_SERIALIZED_MAGIC)) {
420                 close(auth_file_fd);
421                 empty_auth_file();
422                 return;
423         }
424
425         assert(read(auth_file_fd, &x, 4) == 4);
426         assert(x > 0);
427         int dc_working_num;
428         assert(read(auth_file_fd, &dc_working_num, 4) == 4);
429
430         int i;
431         for(i = 0; i <=(int)x; i++) {
432                 int y;
433                 assert(read(auth_file_fd, &y, 4) == 4);
434                 if (y) {
435                         read_dc(auth_file_fd, i, m);
436                 }
437         }
438
439         bl_do_set_working_dc(s_info.TLS, dc_working_num);
440         int our_id;
441         int l = read(auth_file_fd, &our_id, 4);
442
443         if (l < 4) {
444                 assert(!l);
445         }
446         if (our_id) {
447                 bl_do_set_our_id(s_info.TLS, our_id);
448         }
449         close(auth_file_fd);
450 }
451
452 void tg_new_msg(struct tgl_state *TLS, struct tgl_message *M)
453 {
454         struct tgl_message *temp_msg = tgl_message_get(TLS, M->id);
455         if (temp_msg) {
456
457         }
458 }
459
460 void tg_marked_read(struct tgl_state *TLS, int num, struct tgl_message *list[])
461 {
462         for (int i = 0; i < num; i++) {
463                 //struct tgl_message
464                 struct tgl_message* message = list[i];
465                 int identifier = -1;
466                 tgl_peer_t* UC;
467                 UC = tgl_peer_get(TLS, message->to_id);
468                 struct tgl_user* buddy;
469                 buddy = &(UC->user);
470                 char *phone = NULL;
471                 if (buddy && buddy->phone && strlen(buddy->phone) > 0) {
472                         phone = buddy->phone;
473                 }
474
475                 message->msg_state = TG_MESSAGE_STATE_READ;
476
477                 char *tb_name = get_table_name_from_number(message->to_id.id);
478                 update_msg_into_db(message, tb_name, identifier);
479                 if (message->media.type == tgl_message_media_photo) {
480                         update_sent_media_info_in_db(message, (long long)message->media.photo.id);
481                 }
482                 send_message_read_by_buddy_response(TLS->callback_data, message->to_id.id, message->id, tb_name, phone, tgl_get_peer_type(message->to_id));
483                 free(tb_name);
484         }
485
486 }
487
488 void tg_logprintf(const char *format, ...)
489 {
490
491 }
492
493 void on_code_via_phone_result(struct tgl_state *TLS, void *callback_extra, int success)
494 {
495         if (success) {
496                 printf("success");
497         }
498 }
499
500 void request_for_code_via_call(struct tgl_state *TLS, char* phone_no, Eina_Bool trough_sms)
501 {
502         tg_engine_data_s *tg_data;
503         tg_data = TLS->callback_data;
504         if (tg_data && tg_data->phone_number && tg_data->mhash) {
505                 tgl_do_phone_call(TLS, tg_data->phone_number, tg_data->mhash, on_code_via_phone_result, TLS);
506         }
507 }
508
509 void tg_get_string(struct tgl_state *TLS, const char *prompt, int flags, void(*callback)(struct tgl_state *TLS, char *string, void *arg), void *arg)
510 {
511         tg_engine_data_s *tg_data;
512
513         tg_data = TLS->callback_data;
514
515         tg_data->get_string = callback;
516         tg_data->callback_arg = arg;
517         if (strcmp (prompt, "phone number:") == 0) {
518
519                 if (tg_data->tg_state == TG_ENGINE_STATE_REGISTRATION) {
520                         send_request_phone_num_again(tg_data);
521                 } else {
522                         //tg_data->is_first_time_registration = EINA_TRUE;
523                         tg_data->tg_state = TG_ENGINE_STATE_REGISTRATION;
524                         if (tg_data && tg_data->phone_number) {
525                                 tg_data->get_string(TLS, tg_data->phone_number, tg_data->callback_arg);
526                                 tg_data->code_response_timer = ecore_timer_add(60, on_code_request_timer_expired, tg_data);
527                         }
528                 }
529         } else if (strcmp (prompt, "code('call' for phone call):") == 0) {
530
531                 if (tg_data->code_response_timer) {
532                         ecore_timer_del(tg_data->code_response_timer);
533                         tg_data->code_response_timer = NULL;
534                 }
535
536                 void **T = arg;
537                 tg_data->mhash = strdup(T[1]);
538
539                 if (tg_data->tg_state == TG_ENGINE_STATE_CODE_REQUEST) {
540                         send_request_code_again(tg_data);
541                 } else {
542                         tg_data->tg_state = TG_ENGINE_STATE_CODE_REQUEST;
543                         send_registration_response(tg_data, EINA_TRUE);
544                 }
545
546         } else if (strcmp (prompt, "register [Y/n]:") == 0) {
547
548                 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_REGISTRATION;
549                 tg_data->get_string(TLS, "Y", tg_data->callback_arg);
550
551         } else if (strcmp (prompt, "First name:") == 0) {
552                 // request for first name
553
554                 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_FIRST_NAME_REGISTRATION;
555                 tg_data->is_first_time_registration = EINA_TRUE;
556
557                 if (tg_data->first_name) {
558                         tg_data->get_string(TLS, tg_data->first_name, tg_data->callback_arg);
559                 } else {
560                         send_name_registration_response(tg_data);
561                 }
562
563         } else if (strcmp (prompt, "Last name:") == 0) {
564                 // request for last name
565                 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_LAST_NAME_REGISTRATION;
566
567                 if (tg_data->last_name) {
568                         tg_data->get_string(TLS, tg_data->last_name, tg_data->callback_arg);
569                 }
570
571         } else {
572
573                 // to be checked
574
575         }
576 }
577
578 void tg_logged_in(struct tgl_state *TLS)
579 {
580         tg_engine_data_s *tg_data;
581         tg_data = TLS->callback_data;
582         write_auth_file();
583         int offline_mode = 0;
584         tgl_peer_id_t t_id;
585         t_id.id = TLS->our_id;
586         t_id.type = TGL_PEER_USER;
587         //tg_data->is_first_time_registration = EINA_TRUE;
588         create_data_base_tables();
589         tgl_do_get_user_info(TLS, t_id, offline_mode, &on_user_info_loaded, NULL);
590 }
591
592 static Eina_Bool on_send_media_message_requested(void *data)
593 {
594         sent_media_data_s *media_info = (sent_media_data_s*)data;
595         if (media_info) {
596                 int buddy_id = atoi(media_info->buddy_id);
597                 int message_id = atoi(media_info->message_id);
598                 int media_id = atoi(media_info->media_id);
599                 int msg_type = atoi(media_info->message_type);
600                 int type_of_chat = atoi(media_info->type_of_chat);
601
602                 process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
603
604                 if (media_info->app_name) {
605                         free(media_info->app_name);
606                         media_info->app_name = NULL;
607                 }
608                 if (media_info->command) {
609                         free(media_info->command);
610                         media_info->command = NULL;
611                 }
612                 if (media_info->buddy_id) {
613                         free(media_info->buddy_id);
614                         media_info->buddy_id = NULL;
615                 }
616                 if (media_info->message_id) {
617                         free(media_info->message_id);
618                         media_info->message_id = NULL;
619                 }
620                 if (media_info->media_id) {
621                         free(media_info->media_id);
622                         media_info->media_id = NULL;
623                 }
624
625                 if (media_info->message_type) {
626                         free(media_info->message_type);
627                         media_info->message_type = NULL;
628                 }
629                 if (media_info->file_path) {
630                         free(media_info->file_path);
631                         media_info->file_path = NULL;
632                 }
633                 if (media_info->type_of_chat) {
634                         free(media_info->type_of_chat);
635                         media_info->type_of_chat = NULL;
636                 }
637                 free(media_info);
638         }
639         return ECORE_CALLBACK_CANCEL;
640 }
641 static Eina_Bool on_load_offline_messages(void *data);
642 static Eina_Bool on_send_unsent_messages_requested(void *data)
643 {
644         struct tgl_state *TLS = data;
645         if (TLS) {
646                 //tg_engine_data_s *tg_data = TLS->callback_data;
647
648                 Eina_List *unset_text_msgs = get_all_unsent_text_messages();
649                 if (unset_text_msgs && eina_list_count(unset_text_msgs) > 0 ) {
650                         for (int i = 0 ; i < eina_list_count(unset_text_msgs) ; i++) {
651                                 sent_message_data_s* msg_info = eina_list_nth(unset_text_msgs, i);
652                                 if (msg_info) {
653                                         int buddy_id = atoi(msg_info->buddy_id);
654                                         int message_id = atoi(msg_info->message_id);
655                                         int msg_type = atoi(msg_info->message_type);
656                                         int type_of_chat = atoi(msg_info->type_of_chat);
657                                         process_send_message_command(buddy_id, message_id, msg_type, msg_info->message_data, type_of_chat);
658
659                                         if (msg_info->app_name) {
660                                                 free(msg_info->app_name);
661                                                 msg_info->app_name = NULL;
662                                         }
663                                         if (msg_info->command) {
664                                                 free(msg_info->command);
665                                                 msg_info->command = NULL;
666                                         }
667                                         if (msg_info->buddy_id) {
668                                                 free(msg_info->buddy_id);
669                                                 msg_info->buddy_id = NULL;
670                                         }
671                                         if (msg_info->message_id) {
672                                                 free(msg_info->message_id);
673                                                 msg_info->message_id = NULL;
674                                         }
675
676                                         if (msg_info->message_type) {
677                                                 free(msg_info->message_type);
678                                                 msg_info->message_type = NULL;
679                                         }
680                                         if (msg_info->message_data) {
681                                                 free(msg_info->message_data);
682                                                 msg_info->message_data = NULL;
683                                         }
684                                         if (msg_info->type_of_chat) {
685                                                 free(msg_info->type_of_chat);
686                                                 msg_info->type_of_chat = NULL;
687                                         }
688                                         free(msg_info);
689                                 }
690
691                         }
692                         eina_list_free(unset_text_msgs);
693                 }
694
695                 Eina_List *unset_media_msgs = get_all_unsent_media_messages();
696                 int init_time = 10;
697                 if (unset_media_msgs && eina_list_count(unset_media_msgs) > 0 ) {
698                         for (int i = 0 ; i < eina_list_count(unset_media_msgs) ; i++) {
699                                 sent_media_data_s* media_info = eina_list_nth(unset_media_msgs, i);
700                                 if (media_info) {
701 /*                                      int buddy_id = atoi(media_info->buddy_id);
702                                         int message_id = atoi(media_info->message_id);
703                                         int media_id = atoi(media_info->media_id);
704                                         int msg_type = atoi(media_info->message_type);
705                                         int type_of_chat = atoi(media_info->type_of_chat);*/
706
707                                         sent_media_data_s* new_media_info = (sent_media_data_s*)malloc(sizeof(sent_media_data_s));
708                                         new_media_info->app_name = strdup(media_info->app_name);
709                                         new_media_info->command = strdup(media_info->command);
710                                         new_media_info->buddy_id = strdup(media_info->buddy_id);
711                                         new_media_info->message_id = strdup(media_info->message_id);
712                                         new_media_info->media_id = strdup(media_info->media_id);
713                                         new_media_info->message_type = strdup(media_info->message_type);
714                                         new_media_info->file_path = strdup(media_info->file_path);
715                                         new_media_info->type_of_chat = strdup(media_info->type_of_chat);
716
717                                         ecore_timer_add(init_time, on_send_media_message_requested, new_media_info);
718
719                                         //process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
720
721                                         if (media_info->app_name) {
722                                                 free(media_info->app_name);
723                                                 media_info->app_name = NULL;
724                                         }
725                                         if (media_info->command) {
726                                                 free(media_info->command);
727                                                 media_info->command = NULL;
728                                         }
729                                         if (media_info->buddy_id) {
730                                                 free(media_info->buddy_id);
731                                                 media_info->buddy_id = NULL;
732                                         }
733                                         if (media_info->message_id) {
734                                                 free(media_info->message_id);
735                                                 media_info->message_id = NULL;
736                                         }
737                                         if (media_info->media_id) {
738                                                 free(media_info->media_id);
739                                                 media_info->media_id = NULL;
740                                         }
741
742                                         if (media_info->message_type) {
743                                                 free(media_info->message_type);
744                                                 media_info->message_type = NULL;
745                                         }
746                                         if (media_info->file_path) {
747                                                 free(media_info->file_path);
748                                                 media_info->file_path = NULL;
749                                         }
750                                         if (media_info->type_of_chat) {
751                                                 free(media_info->type_of_chat);
752                                                 media_info->type_of_chat = NULL;
753                                         }
754                                         free(media_info);
755                                 }
756
757                         }
758                         eina_list_free(unset_media_msgs);
759                 }
760                 ecore_timer_add(5, on_load_offline_messages, TLS);
761         }
762     return ECORE_CALLBACK_CANCEL;
763 }
764
765 void tg_started(struct tgl_state *TLS)
766 {
767         tg_engine_data_s *tg_data = TLS->callback_data;
768         tg_data->is_login_activated = EINA_TRUE;
769 }
770
771 void tg_type_notification(struct tgl_state *TLS, struct tgl_user* buddy, enum tgl_typing_status status)
772 {
773         char *name_of_buddy = NULL;
774
775         if (buddy->first_name && buddy->last_name) {
776                 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
777                 strcpy(name_of_buddy, buddy->first_name);
778                 strcat(name_of_buddy, buddy->last_name);
779         } else if(buddy->first_name) {
780                 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
781                 strcpy(name_of_buddy, buddy->first_name);
782         } else {
783                 name_of_buddy = (char *)malloc(strlen(" ") + 1);
784                 strcpy(name_of_buddy, " ");
785         }
786
787         send_buddy_type_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, status);
788
789         if (name_of_buddy) {
790                 free(name_of_buddy);
791                 name_of_buddy = NULL;
792         }
793 }
794
795 void tg_type_in_chat_notification(struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status)
796 {
797
798 }
799
800 void tg_type_in_secret_chat_notification(struct tgl_state *TLS, struct tgl_secret_chat *E)
801 {
802
803 }
804
805 void tg_status_notification(struct tgl_state *TLS, struct tgl_user *buddy)
806 {
807         if (buddy) {
808                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
809
810                 char *name_of_buddy = NULL;
811
812                 if (buddy->first_name && buddy->last_name) {
813                         name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
814                         strcpy(name_of_buddy, buddy->first_name);
815                         strcat(name_of_buddy, buddy->last_name);
816                 } else if(buddy->first_name) {
817                         name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
818                         strcpy(name_of_buddy, buddy->first_name);
819                 } else {
820                         name_of_buddy = (char *)malloc(strlen(" ") + 1);
821                         strcpy(name_of_buddy, " ");
822                 }
823
824                 send_buddy_status_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, buddy->status.online);
825
826                 if (name_of_buddy) {
827                         free(name_of_buddy);
828                         name_of_buddy = NULL;
829                 }
830
831         }
832 }
833
834 void tg_user_registered(struct tgl_state *TLS, struct tgl_user *U)
835 {
836
837 }
838
839 void tg_user_activated(struct tgl_state *TLS, struct tgl_user *U)
840 {
841
842 }
843
844 void tg_new_authorization(struct tgl_state *TLS, const char *device, const char *location)
845 {
846
847 }
848
849 void tg_chat_update(struct tgl_state *TLS, struct tgl_chat* chat_info, unsigned flags)
850 {
851         tg_engine_data_s *tg_data;
852         tg_data = TLS->callback_data;
853
854         if (chat_info && chat_info->flags == 144) {
855                 return;
856         }
857
858         if (flags == TGL_GROUP_CHAT_CREATED) {
859 #if 0
860                 insert_chat_info_to_db(chat_info, NULL);
861                 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
862                 insert_peer_into_database(UC, 0, 0);
863 #endif
864                 //if (tg_data->is_loading_completed) {
865                         tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
866                 //}
867         }
868
869         if (!(flags & TGL_UPDATE_CREATED)) {
870
871                 if (!(flags & TGL_UPDATE_DELETED)) {
872                         //printf("updated");
873                 } else {
874                         //printf("deleted");
875                 }
876         }
877
878 }
879
880 static inline void send_message(tg_engine_data_s *tg_data, struct tgl_user *buddy, const char *str, const char *name_of_buddy, int name_of_buddy_len)
881 {
882         char *update_msg;
883         int len;
884
885         /**
886          * "%s phone number updated" will be changed to IDS_STRING for i18n.
887          */
888         len = name_of_buddy_len + strlen(str);
889         update_msg = (char *)malloc(len + 1);
890         if (!update_msg) {
891                 return;
892         }
893
894         snprintf(update_msg, len, str, name_of_buddy);
895         send_contact_updated_response(tg_data, buddy->id.id, update_msg);
896         free(update_msg);
897 }
898
899 void tg_user_update(struct tgl_state *TLS, struct tgl_user *buddy, unsigned flags)
900 {
901         char *name_of_buddy;
902         int name_of_buddy_len;
903         static const char *NO_NAME = " ";
904
905         if (flags & TGL_UPDATE_CREATED) {
906                 return;
907         }
908
909         if (buddy->first_name && buddy->last_name) {
910                 int first_len = strlen(buddy->first_name);
911                 int last_len = strlen(buddy->last_name);
912
913                 name_of_buddy_len = first_len + last_len;
914
915                 name_of_buddy = (char *)malloc(name_of_buddy_len + 1);
916
917                 strcpy(name_of_buddy, buddy->first_name);
918                 strcpy(name_of_buddy + first_len, buddy->last_name);
919         } else if(buddy->first_name) {
920                 name_of_buddy = strdup(buddy->first_name);
921                 name_of_buddy_len = strlen(name_of_buddy);
922         } else {
923                 name_of_buddy = (char *)NO_NAME;
924                 name_of_buddy_len = strlen(NO_NAME);
925         }
926
927         if (!name_of_buddy) {
928                 /**
929                  * @note
930                  * Unable to allocate heap for buddy name
931                  */
932                 name_of_buddy = (char *)NO_NAME;
933                 name_of_buddy_len = strlen(NO_NAME);
934         }
935
936         if (!(flags & TGL_UPDATE_DELETED)) {
937                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
938
939                 if (flags & TGL_UPDATE_PHONE) {
940                         send_message(TLS->callback_data, buddy, "%s phone number updated.", name_of_buddy, name_of_buddy_len);
941                 }
942                 if (flags & TGL_UPDATE_CONTACT) {
943                         send_message(TLS->callback_data, buddy, "%s contact updated.", name_of_buddy, name_of_buddy_len);
944                 }
945                 if (flags & TGL_UPDATE_PHOTO) {
946                         send_message(TLS->callback_data, buddy, "%s photo updated.", name_of_buddy, name_of_buddy_len);
947                         //tgl_do_get_user_info(TLS, buddy->id, 0, &on_buddy_info_loaded, NULL);
948                 }
949                 if (flags & TGL_UPDATE_BLOCKED) {
950                         send_message(TLS->callback_data, buddy, "%s contact blocked.", name_of_buddy, name_of_buddy_len);
951                 }
952                 if (flags & TGL_UPDATE_REAL_NAME) {
953                         send_message(TLS->callback_data, buddy, "%s name updated.", name_of_buddy, name_of_buddy_len);
954                 }
955                 if (flags & TGL_UPDATE_NAME) {
956                         send_message(TLS->callback_data, buddy, "%s contact name updated.", name_of_buddy, name_of_buddy_len);
957                 }
958                 if (flags & TGL_UPDATE_REQUESTED) {
959                         send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
960                 }
961                 if (flags & TGL_UPDATE_WORKING) {
962                         send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
963                 }
964                 if (flags & TGL_UPDATE_FLAGS) {
965                         send_message(TLS->callback_data, buddy, "%s flags updated.", name_of_buddy, name_of_buddy_len);
966                 }
967                 if (flags & TGL_UPDATE_TITLE) {
968                         send_message(TLS->callback_data, buddy, "%s title updated.", name_of_buddy, name_of_buddy_len);
969                 }
970                 if (flags & TGL_UPDATE_ADMIN) {
971                         send_message(TLS->callback_data, buddy, "%s admin updated.", name_of_buddy, name_of_buddy_len);
972                 }
973                 if (flags & TGL_UPDATE_MEMBERS) {
974                         send_message(TLS->callback_data, buddy, "%s memgers updated.", name_of_buddy, name_of_buddy_len);
975                 }
976                 if (flags & TGL_UPDATE_ACCESS_HASH) {
977                         send_message(TLS->callback_data, buddy, "%s access hash updated.", name_of_buddy, name_of_buddy_len);
978                 }
979                 if (flags & TGL_UPDATE_USERNAME) {
980                         send_message(TLS->callback_data, buddy, "%s username updated.", name_of_buddy, name_of_buddy_len);
981                 }
982         } else {
983                 send_message(TLS->callback_data, buddy, "%s contact deleted.", name_of_buddy, name_of_buddy_len);
984         }
985
986         if (name_of_buddy != NO_NAME) {
987                 free(name_of_buddy);
988                 name_of_buddy = NULL;
989         }
990 }
991
992 void tg_secret_chat_update(struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags)
993 {
994
995 }
996
997 void on_new_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
998 {
999         tg_engine_data_s *tg_data;
1000
1001         struct tgl_message *M = callback_extra;
1002
1003         if (!chat_info) {
1004                 return;
1005         }
1006
1007         if (chat_info->user_list) {
1008                 for (int i = 0; i < chat_info->user_list_size; i++) {
1009                         int user_id = chat_info->user_list[i].user_id;
1010                         Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1011                         char* tb_name = get_table_name_from_number(user_id);
1012                         create_buddy_msg_table(tb_name);
1013                         if (!is_present_in_db) {
1014                                 // add to buddy table
1015                                 tgl_peer_id_t from_id;
1016                                 from_id.id = user_id;
1017                                 from_id.type = TGL_PEER_USER;
1018                                 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1019                         }
1020                         free(tb_name);
1021                 }
1022         }
1023
1024         tg_data = TLS->callback_data;
1025
1026         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1027         int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1028         char* creator_name = (char*)malloc(msg_len);
1029         strcpy(creator_name, UC->user.first_name);
1030         strcat(creator_name, " created the group");
1031
1032         int cur_time = time(NULL);
1033         M->id = chat_info->id.id;
1034         M->message = creator_name;
1035         M->message_len = msg_len;
1036         M->unread = 1;
1037         M->date = cur_time;
1038         insert_buddy_msg_to_db(M);
1039         free(creator_name);
1040
1041         tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1042         insert_chat_info_to_db(chat_info, NULL);
1043         chat_UC->last = M;
1044         insert_peer_into_database(chat_UC, 0, 0, 0);
1045
1046         send_new_group_added_response(tg_data, chat_info->id.id);
1047
1048 }
1049
1050 void on_group_chat_info_updated(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1051 {
1052         tg_engine_data_s *tg_data;
1053
1054
1055         if (!chat_info) {
1056                 return;
1057         }
1058
1059         tg_data = TLS->callback_data;
1060         char *type_of_change = callback_extra;
1061
1062         if (!type_of_change) {
1063                 type_of_change = strdup("");
1064         }
1065
1066         tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1067         insert_chat_info_to_db(chat_info, NULL);
1068         insert_peer_into_database(chat_UC, 0, 0, 0);
1069         send_group_chat_updated_response(tg_data, chat_info->id.id, type_of_change);
1070         free(type_of_change);
1071 }
1072
1073 void on_new_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1074 {
1075         struct tgl_message *M = callback_extra;
1076
1077
1078         if (filename) {
1079
1080                 tgl_peer_t* peer = tgl_peer_get(TLS, M->from_id);
1081                 int msg_len = strlen(peer->user.first_name) + strlen(" changed group icon") + 1;
1082                 char* creator_name = (char*)malloc(msg_len);
1083                 strcpy(creator_name, peer->user.first_name);
1084                 strcat(creator_name, " changed group icon");
1085
1086                 int cur_time = time(NULL);
1087                 M->id = cur_time;
1088                 M->message = creator_name;
1089                 M->message_len = msg_len;
1090                 M->date = cur_time;
1091                 M->unread = 1;
1092                 insert_buddy_msg_to_db(M);
1093                 free(creator_name);
1094                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1095
1096
1097                 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
1098                 struct tgl_chat *chat_info = &(UC->chat);
1099                 update_chat_info_to_db(chat_info, filename);
1100                 update_peer_info_database(UC, 0);
1101                 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1102                 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1103         }
1104 }
1105
1106 void on_media_sticker_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1107 {
1108         struct tgl_message *M = (struct tgl_message*)callback_extra;
1109         if (success && filename) {
1110                 // update in db and send info to app...
1111                 long long media_id = M->media.document.id;
1112                 update_receive_media_info_in_db(media_id, filename);
1113                 tg_engine_data_s *tg_data = TLS->callback_data;
1114                 if (M->from_id.id == tg_data->id.id) {
1115
1116                 } else {
1117                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1118                 }
1119         }
1120 }
1121
1122 void on_video_thumb_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1123 {
1124         struct tgl_message *M = (struct tgl_message*)callback_extra;
1125         if (success && filename) {
1126                 // update in db and send info to app...
1127                 long long media_id = M->media.document.id;
1128                 update_video_thumb_in_db(media_id, filename);
1129                 tg_engine_data_s *tg_data = TLS->callback_data;
1130                 if (M->from_id.id == tg_data->id.id) {
1131                         send_video_thumb_download_completed_response(tg_data, M->from_id.id, M->to_id.id, media_id, filename, NULL);
1132                 } else {
1133                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1134                 }
1135         }
1136 }
1137
1138 struct tg_temp_msg_data {
1139         Ecore_Timer* send_timer;
1140         struct tgl_state *TLS;
1141         struct tgl_message *M;
1142 };
1143
1144 static Eina_Bool on_msg_received_cb(void *data)
1145 {
1146         struct tg_temp_msg_data *msg_data = data;
1147         insert_buddy_msg_to_db(msg_data->M);
1148         if(msg_data->M->media.type != tgl_message_media_none) {
1149                 insert_media_info_to_db(msg_data->M, "");
1150                 if (msg_data->M->media.type != tgl_message_media_none && (msg_data->M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1151                         tgl_do_load_document_thumb(msg_data->TLS, &(msg_data->M->media.document), on_video_thumb_loaded, msg_data->M);
1152                         if (msg_data->send_timer) {
1153                                 ecore_timer_del(msg_data->send_timer);
1154                         }
1155                         free(msg_data);
1156                         return ECORE_CALLBACK_CANCEL;
1157                 }
1158         }
1159         // inform to application
1160         send_message_received_response(msg_data->TLS->callback_data, msg_data->M->from_id.id, msg_data->M->to_id.id, msg_data->M->id, tgl_get_peer_type(msg_data->M->to_id));
1161         if (msg_data->send_timer) {
1162                 ecore_timer_del(msg_data->send_timer);
1163         }
1164         free(msg_data);
1165         return ECORE_CALLBACK_CANCEL;
1166 }
1167
1168 void on_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1169 {
1170         tg_engine_data_s *tg_data;
1171
1172         struct tgl_message *M = callback_extra;
1173
1174         char *msg_table;
1175
1176
1177         if (!chat_info) {
1178                 return;
1179         }
1180         if (!chat_info->user_list) {
1181                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
1182                 return;
1183         }
1184
1185         tg_data = TLS->callback_data;
1186
1187         msg_table = get_table_name_from_number(chat_info->id.id);
1188
1189         create_buddy_msg_table(msg_table);
1190
1191         insert_chat_info_to_db(chat_info, NULL);
1192         struct tgl_photo *pic = &(chat_info->photo);
1193         if(pic) {
1194                 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
1195         }
1196
1197         // send message
1198         int msg_id = insert_current_date_to_table(msg_table);
1199         if (msg_id > 0) {
1200                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1201                 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1202                 msg_data->M = M;
1203                 msg_data->TLS = TLS;
1204                 msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1205         } else {
1206                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1207                         M->message = strdup("Audio");
1208                         M->message_len = strlen("Audio");
1209                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1210                         M->message = strdup("Video");
1211                         M->message_len = strlen("Video");
1212                 }
1213                 insert_buddy_msg_to_db(M);
1214                 if(M->media.type != tgl_message_media_none) {
1215                         insert_media_info_to_db(M, "");
1216                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1217                                 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1218                                 return;
1219                         }
1220                 }
1221                 // inform to application
1222                 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1223         }
1224
1225         free(msg_table);
1226 }
1227
1228
1229 void on_requested_update_chat_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1230 {
1231         tg_engine_data_s *tg_data;
1232         char *msg_table;
1233         msg_table = get_table_name_from_number(chat_info->id.id);
1234         create_buddy_msg_table(msg_table);
1235
1236         if (!chat_info) {
1237                 return;
1238         }
1239
1240         if (chat_info->flags == 144) {
1241                 return;
1242         }
1243         int msg_count = get_number_of_messages(msg_table);
1244         if (msg_count <= 0) {
1245                 if (chat_info->admin_id > 0) {
1246                         set_date_item_to_table(msg_table, chat_info->date);
1247                         tgl_peer_id_t admin_id;
1248                         admin_id.id = chat_info->admin_id;
1249                         admin_id.type = TGL_PEER_USER;
1250
1251                         tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1252                         int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1253                         char* creator_name = (char*)malloc(msg_len);
1254                         strcpy(creator_name, UC->user.first_name);
1255                         strcat(creator_name, " created the group");
1256                         struct tgl_message msg;
1257                         int cur_time = chat_info->date;
1258                         msg.to_id = chat_info->id;
1259                         msg.from_id = admin_id;
1260                         msg.id = chat_info->id.id;
1261                         msg.message = creator_name;
1262                         msg.message_len = msg_len;
1263                         msg.unread = 0;
1264                         msg.date = cur_time;
1265                         msg.media.type = tgl_message_media_none;
1266                         msg.service = 1;
1267                         msg.out = 0;
1268
1269                         insert_buddy_msg_to_db(&msg);
1270                         free(creator_name);
1271                         //send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1272                 }
1273
1274         }
1275
1276         free(msg_table);
1277
1278         if (!chat_info->user_list) {
1279                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1280                 return;
1281         }
1282
1283         tg_data = TLS->callback_data;
1284
1285         insert_chat_info_to_db(chat_info, NULL);
1286         struct tgl_photo *pic = &(chat_info->photo);
1287         if(pic) {
1288                 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
1289         }
1290         //char *type_of_change = strdup("add_user");
1291         tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1292         insert_chat_info_to_db(chat_info, NULL);
1293         insert_peer_into_database(chat_UC, 0, 0, 0);
1294         send_response_to_group_chat_updated_response(tg_data, chat_info->id.id);
1295         //free(type_of_change);
1296 }
1297
1298 void do_update_chat_info(int chat_id)
1299 {
1300         tgl_peer_id_t to_id;
1301         to_id.id = chat_id;
1302         to_id.type = TGL_PEER_CHAT;
1303         tgl_do_get_chat_info(s_info.TLS, to_id, 0, &on_requested_update_chat_received, NULL);
1304 }
1305
1306 void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1307 {
1308         if(!U) {
1309                 return;
1310         }
1311         tg_engine_data_s *tg_data = TLS->callback_data;
1312         struct tgl_message *M = callback_extra;
1313         if (U->id.id == tg_data->id.id) {
1314                 return;
1315         }
1316         tgl_peer_t* UC = tgl_peer_get(TLS, U->id);
1317         insert_peer_into_database(UC, 0, 0, 1);
1318         U->is_unknown = 1;
1319         init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1320         struct tgl_photo* pic = &(U->photo);
1321         if(pic) {
1322                 tgl_do_load_photo(TLS, pic ,&on_buddy_pic_loaded,U);
1323         }
1324
1325         send_new_buddy_added_response(tg_data, U->id.id);
1326
1327         if (M) {
1328                 char* tb_name = get_table_name_from_number(U->id.id);
1329                 int msg_id = insert_current_date_to_table(tb_name);
1330                 free(tb_name);
1331                 if (msg_id > 0) {
1332                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1333
1334                         struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1335                         msg_data->M = M;
1336                         msg_data->TLS = TLS;
1337                         msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1338                 } else {
1339                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1340                                 M->message = strdup("Audio");
1341                                 M->message_len = strlen("Audio");
1342                         } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1343                                 M->message = strdup("Video");
1344                                 M->message_len = strlen("Video");
1345                         }
1346                         insert_buddy_msg_to_db(M);
1347                         if(M->media.type != tgl_message_media_none) {
1348                                 insert_media_info_to_db(M, "");
1349                                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1350                                         tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1351                                         return;
1352                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1353
1354                                 }
1355                         }
1356                         // inform to application
1357                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1358                 }
1359         }
1360 }
1361
1362 void tg_msg_receive(struct tgl_state *TLS, struct tgl_message *M)
1363 {
1364         if (M && TLS->started) {
1365
1366                 if (M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) {
1367                         return;
1368                 }
1369                 if (!(M->flags & FLAG_CREATED)) {
1370                         return;
1371                 }
1372                 if (M->service) {
1373                         // this is service message. to be handled in telegram.
1374                         if (tgl_get_peer_id (M->from_id) != TLS->our_id) {
1375                                 char *type_of_change = NULL;
1376                                 if (M->action.type == tgl_message_action_chat_create) {
1377
1378                                         char* msg_table = get_table_name_from_number(M->to_id.id);
1379                                         create_buddy_msg_table(msg_table);
1380                                         int msg_id = insert_current_date_to_table(msg_table);
1381                                         free(msg_table);
1382
1383                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_new_chat_info_received, M);
1384
1385                                 } else if (M->action.type == tgl_message_action_chat_edit_title) {
1386                                         type_of_change = strdup("edit_title");
1387                                         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1388                                         int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
1389                                         char* creator_name = (char*)malloc(msg_len);
1390                                         strcpy(creator_name, UC->user.first_name);
1391                                         strcat(creator_name, " changed the chat title");
1392
1393                                         int cur_time = time(NULL);
1394                                         M->id = cur_time;
1395                                         M->message = creator_name;
1396                                         M->message_len = msg_len;
1397                                         M->unread = 1;
1398                                         M->date = cur_time;
1399                                         insert_buddy_msg_to_db(M);
1400                                         free(creator_name);
1401                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1402                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1403                                 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
1404
1405                                         char* msg_table = get_table_name_from_number(M->to_id.id);
1406                                         create_buddy_msg_table(msg_table);
1407                                         int msg_id = insert_current_date_to_table(msg_table);
1408                                         free(msg_table);
1409                                         struct tgl_photo *pic = &(M->action.photo);
1410                                         if(pic) {
1411                                                 tgl_do_load_photo(TLS, pic ,&on_new_chat_pic_loaded, M);
1412                                         }
1413
1414                                 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
1415                                         type_of_change = strdup("delete_photo");
1416                                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
1417                                         int msg_len = strlen(UC->user.first_name) + strlen(" deleted the profile photo") + 1;
1418                                         char* creator_name = (char*)malloc(msg_len);
1419                                         strcpy(creator_name, UC->user.first_name);
1420                                         strcat(creator_name, " deleted the profile photo");
1421
1422                                         int cur_time = time(NULL);
1423                                         M->id = cur_time;
1424                                         M->message = creator_name;
1425                                         M->message_len = msg_len;
1426                                         M->unread = 1;
1427                                         M->date = cur_time;
1428                                         insert_buddy_msg_to_db(M);
1429                                         free(creator_name);
1430                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1431
1432
1433                                         char *filename = "";
1434                                         tgl_peer_t* lUC = tgl_peer_get(TLS, M->to_id);
1435                                         struct tgl_chat *chat_info = &(lUC->chat);
1436                                         update_chat_info_to_db(chat_info, filename);
1437                                         update_peer_info_database(lUC, 0);
1438                                         update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1439                                         send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1440
1441
1442                                 } else if (M->action.type == tgl_message_action_chat_add_user) {
1443                                         type_of_change = strdup("add_user");
1444                                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
1445                                         int msg_len = strlen(UC->user.first_name) + strlen(" added to the group") + 1;
1446                                         char* creator_name = (char*)malloc(msg_len);
1447                                         strcpy(creator_name, UC->user.first_name);
1448                                         strcat(creator_name, " added to the group");
1449
1450                                         int cur_time = time(NULL);
1451                                         M->id = cur_time;
1452                                         M->message = creator_name;
1453                                         M->message_len = msg_len;
1454                                         M->unread = 1;
1455                                         M->date = cur_time;
1456                                         insert_buddy_msg_to_db(M);
1457                                         free(creator_name);
1458                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1459                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1460                                 } else if (M->action.type == tgl_message_action_chat_delete_user) {
1461                                         type_of_change = strdup("delete_user");
1462                                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
1463                                         int msg_len = strlen(UC->user.first_name) + strlen(" left the group") + 1;
1464                                         char* creator_name = (char*)malloc(msg_len);
1465                                         strcpy(creator_name, UC->user.first_name);
1466                                         strcat(creator_name, " left the group");
1467
1468                                         int cur_time = time(NULL);
1469                                         M->id = cur_time;
1470                                         M->message = creator_name;
1471                                         M->message_len = msg_len;
1472                                         M->unread = 1;
1473                                         M->date = cur_time;
1474                                         insert_buddy_msg_to_db(M);
1475                                         free(creator_name);
1476                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1477                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1478                                 }
1479                         }
1480                         return;
1481                 }
1482
1483                 if (!tgl_get_peer_type(M->to_id)) {
1484                         // bad message
1485                         return;
1486                 }
1487
1488                 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1489                         if (M->out) {
1490                                 if (M->unread) {
1491
1492                                 } else {
1493
1494                                 }
1495                         } else {
1496                                 if (M->media.type != tgl_message_media_none) {
1497                                         M->message = NULL;
1498                                         M->message_len = 0;
1499                                 }
1500
1501                                 int user_id = M->from_id.id;
1502 #if 0
1503                                 Eina_Bool is_present_in_db = is_user_present_peer_table(user_id);
1504                                 char* tb_name = get_table_name_from_number(user_id);
1505                                 create_buddy_msg_table(tb_name);
1506                                 if (!is_present_in_db) {
1507                                         // add to buddy table
1508                                         tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, NULL);
1509                                 }
1510 #else
1511                                 char* tb_name = get_table_name_from_number(user_id);
1512                                 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1513                                 create_buddy_msg_table(tb_name);
1514                                 if (!is_present_in_db) {
1515                                         tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, M);
1516                                         free(tb_name);
1517                                         return;
1518                                 }
1519 #endif
1520                                 int msg_id = update_current_date_to_table(tb_name, M->date);
1521                                 free(tb_name);
1522
1523
1524                                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1525                                         M->message = strdup("Audio");
1526                                         M->message_len = strlen("Audio");
1527                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1528                                         M->message = strdup("Video");
1529                                         M->message_len = strlen("Video");
1530                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1531                                         M->message = strdup("Sticker");
1532                                         M->message_len = strlen("Sticker");
1533                                 }
1534                                 insert_buddy_msg_to_db(M);
1535                                 if(M->media.type != tgl_message_media_none) {
1536                                         insert_media_info_to_db(M, "");
1537                                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1538                                                 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1539                                                 return;
1540                                         } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1541
1542                                         } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1543                                                 tgl_do_load_document(TLS, &(M->media.document), on_media_sticker_loaded, M);
1544                                                 return;
1545                                         }
1546                                 }
1547                                 // inform to application
1548
1549                                 if (msg_id > 0) {
1550                                         send_message_with_date_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, msg_id, tgl_get_peer_type(M->to_id));
1551                                 } else {
1552                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1553                                 }
1554
1555                         }
1556
1557                 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_ENCR_CHAT) {
1558
1559                 } else {
1560
1561                         if ((tgl_get_peer_type (M->from_id) == TGL_PEER_USER) && (tgl_get_peer_id (M->from_id) == TLS->our_id)) {
1562
1563                         } else {
1564                                 if (M->media.type != tgl_message_media_none) {
1565                                         M->message = NULL;
1566                                         M->message_len = 0;
1567                                 }
1568                                 int user_id = 0;
1569                                 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1570                                         user_id = M->from_id.id;
1571                                 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_CHAT) {
1572                                         user_id = M->to_id.id;
1573                                 }
1574
1575                                 // check whether user is present or not
1576 #if 0
1577                                 Eina_Bool is_present_in_peer_db = is_user_present_buddy_table(user_id);
1578                                 if (!is_present_in_peer_db) {
1579                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1580                                         return;
1581                                 }
1582 #endif
1583
1584                                 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(user_id);
1585                                 if (!is_present_in_chat_db) {
1586                                         //sandeep
1587                                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1588                                         return;
1589                                 }
1590
1591                                 char* tb_name = get_table_name_from_number(user_id);
1592                                 int msg_id = update_current_date_to_table(tb_name, M->date);
1593                                 free(tb_name);
1594
1595                                 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1596                                         M->message = strdup("Audio");
1597                                         M->message_len = strlen("Audio");
1598                                 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1599                                         M->message = strdup("Video");
1600                                         M->message_len = strlen("Video");
1601                                 }
1602                                 insert_buddy_msg_to_db(M);
1603                                 if(M->media.type != tgl_message_media_none) {
1604                                         insert_media_info_to_db(M, "");
1605                                         if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1606                                                 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1607                                                 return;
1608                                         }
1609                                 }
1610                                 // inform to application
1611
1612                                 if (msg_id > 0) {
1613                                         send_message_with_date_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, msg_id, tgl_get_peer_type(M->to_id));
1614                                 } else {
1615                                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1616                                 }
1617                         }
1618                 }
1619         }
1620 }
1621
1622 void tg_our_id(struct tgl_state *TLS, int id)
1623 {
1624
1625 }
1626
1627 void tg_notification(struct tgl_state *TLS, char *type, char *message)
1628 {
1629
1630 }
1631
1632 void tg_user_status_update(struct tgl_state *TLS, struct tgl_user *U)
1633 {
1634
1635         if (tgl_get_peer_type (U->id) != TGL_PEER_USER) {
1636                 return;
1637         }
1638
1639         if (!U) {
1640                 // unknown user
1641         } else {
1642                 if ((U->flags & FLAG_DELETED)) {
1643                         // deleted user
1644                 } else if (!(U->flags & FLAG_CREATED)) {
1645                         // newly created user
1646                 } else {
1647                         // existing user
1648
1649                 }
1650
1651                 if (U->flags & FLAG_USER_SELF) {
1652                         update_buddy_into_db(USER_INFO_TABLE_NAME, U);
1653                 } else if (U->flags & FLAG_USER_CONTACT) {
1654                         update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1655 #if 0
1656                         struct tgl_user_status *S = &(U->status);
1657
1658                         if (S->online > 0) {
1659                                 //online;
1660                         } else {
1661                                 if (S->online == 0) {
1662                                         //"offline
1663                                 } else if (S->online == -1) {
1664                                         //offline was online ");
1665                                 } else if (S->online == -2) {
1666                                         // offline (was online recently)
1667                                 } else if (S->online == -3) {
1668                                         //offline (was online last week)
1669                                 } else if (S->online == -4) {
1670                                         //offline (was online last month)
1671                                 }
1672                         }
1673 #endif
1674                         // update status to application.
1675                         send_buddy_status_updated_response(TLS->callback_data, U->id.id);
1676
1677                 } else {
1678
1679                 }
1680         }
1681
1682 }
1683
1684 char *tg_create_print_name(struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4)
1685 {
1686         return NULL;
1687 }
1688
1689 struct tgl_update_callback upd_cb = {
1690         .new_msg = tg_new_msg,
1691         .marked_read = tg_marked_read,
1692         .logprintf = tg_logprintf,
1693         .get_string = tg_get_string,
1694         .logged_in = tg_logged_in,
1695         .started = tg_started,
1696         .type_notification = tg_type_notification,
1697         .type_in_chat_notification = tg_type_in_chat_notification,
1698         .type_in_secret_chat_notification = tg_type_in_secret_chat_notification,
1699         //.status_notification = tg_status_notification,
1700         .status_notification = NULL,
1701         .user_registered = tg_user_registered,
1702         .user_activated = tg_user_activated,
1703         .new_authorization = tg_new_authorization,
1704         //.user_update = tg_user_update,
1705         .user_update = NULL,
1706         //.chat_update = tg_chat_update,
1707         .chat_update = NULL,
1708         .secret_chat_update = tg_secret_chat_update,
1709         .msg_receive = tg_msg_receive,
1710         .our_id = tg_our_id,
1711         .user_status_update = tg_user_status_update
1712 };
1713
1714 void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1715 {
1716         struct tgl_chat *chat_info = callback_extra;
1717
1718         if (filename) {
1719                 update_chat_info_to_db(chat_info, filename);
1720                 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
1721                 update_peer_info_database(UC, 0);
1722                 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1723                 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1724         }
1725 }
1726
1727 void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1728 {
1729         struct tgl_user *buddy = callback_extra;
1730         tg_engine_data_s *tg_data = TLS->callback_data;
1731
1732         if (buddy && buddy->id.id == tg_data->id.id) {
1733                 if(filename) {
1734                         update_buddy_pic_db(filename, USER_INFO_TABLE_NAME, buddy->id.id);
1735                         update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1736                         send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1737                 }
1738                 return;
1739         }
1740
1741         if (filename) {
1742                 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1743                 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, buddy->id.id);
1744                 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1745         }
1746 }
1747
1748 #if 0
1749 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
1750 {
1751         struct tgl_chat *chat_info = callback_extra;
1752         tg_engine_data_s *tg_data;
1753
1754         tg_data = TLS->callback_data;
1755
1756         if(tg_data->new_group_icon) {
1757
1758                 char *msg_table = get_table_name_from_number(chat_info->id.id);
1759                 create_buddy_msg_table(msg_table);
1760
1761                 char *msg_data = "group icon changed.";
1762                 struct tgl_message msg;
1763                 msg.from_id.id = 0;
1764                 msg.from_id.type = 0;
1765                 msg.date = 0;
1766                 msg.flags = 0;
1767                 msg.fwd_date = 0;
1768                 msg.fwd_from_id.id = 0;
1769                 msg.fwd_from_id.type = 0;
1770                 msg.id = 0;
1771                 msg.message = msg_data;
1772                 msg.message_len = strlen (msg_data);
1773                 msg.out = 0;
1774                 msg.service = 0;
1775                 msg.to_id.id = 0;
1776                 msg.to_id.type = tg_data->id.type;
1777                 msg.unread = 0;
1778                 msg.media.type = -1;
1779                 msg.is_marked_for_delete = 0;
1780                 int t = time(NULL);
1781                 insert_msg_into_db(&msg, msg_table, t);
1782                 free(msg_table);
1783
1784                 update_chat_info_to_db(chat_info, tg_data->new_group_icon);
1785                 update_buddy_pic_db(tg_data->new_group_icon, PEER_INFO_TABLE_NAME, chat_info->id.id);
1786                 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, tg_data->new_group_icon);
1787
1788                 free(tg_data->new_group_icon);
1789                 tg_data->new_group_icon = NULL;
1790         }
1791 }
1792 #endif
1793
1794 void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1795 {
1796         tg_engine_data_s *tg_data;
1797         char *msg_table;
1798
1799         if (!chat_info) {
1800                 return;
1801         }
1802         if (chat_info->flags == 144) {
1803                 return;
1804         }
1805         msg_table = get_table_name_from_number(chat_info->id.id);
1806         create_buddy_msg_table(msg_table);
1807
1808         int msg_count = get_number_of_messages(msg_table);
1809         if (msg_count <= 0) {
1810                 if (chat_info->admin_id > 0) {
1811                         set_date_item_to_table(msg_table, chat_info->date);
1812                         tgl_peer_id_t admin_id;
1813                         admin_id.id = chat_info->admin_id;
1814                         admin_id.type = TGL_PEER_USER;
1815
1816                         tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1817                         int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1818                         char* creator_name = (char*)malloc(msg_len);
1819                         strcpy(creator_name, UC->user.first_name);
1820                         strcat(creator_name, " created the group");
1821                         struct tgl_message msg;
1822                         int cur_time = chat_info->date;
1823                         msg.to_id = chat_info->id;
1824                         msg.from_id = admin_id;
1825                         msg.id = chat_info->id.id;
1826                         msg.message = creator_name;
1827                         msg.message_len = msg_len;
1828                         msg.unread = 0;
1829                         msg.date = cur_time;
1830                         msg.media.type = tgl_message_media_none;
1831                         msg.service = 1;
1832                         msg.out = 0;
1833
1834                         insert_buddy_msg_to_db(&msg);
1835                         free(creator_name);
1836                         send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1837                 }
1838
1839         }
1840
1841         free(msg_table);
1842         if (!chat_info->user_list) {
1843                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1844                 return;
1845         } else {
1846                 for (int i = 0; i < chat_info->user_list_size; i++) {
1847                         int user_id = chat_info->user_list[i].user_id;
1848                         Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1849                         char* tb_name = get_table_name_from_number(user_id);
1850                         create_buddy_msg_table(tb_name);
1851                         if (!is_present_in_db) {
1852                                 // add to buddy table
1853                                 tgl_peer_id_t from_id;
1854                                 from_id.id = user_id;
1855                                 from_id.type = TGL_PEER_USER;
1856                                 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1857                         }
1858                         free(tb_name);
1859                 }
1860         }
1861
1862         tg_data = TLS->callback_data;
1863
1864         insert_chat_info_to_db(chat_info, NULL);
1865         struct tgl_photo *pic = &(chat_info->photo);
1866         if(pic) {
1867                 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
1868         }
1869 }
1870
1871 void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1872 {
1873         if(!U) {
1874                 return;
1875         }
1876         tg_engine_data_s *tg_data = TLS->callback_data;
1877         if (U->id.id == tg_data->id.id) {
1878                 return;
1879         }
1880
1881         //update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1882         struct tgl_photo* pic = &(U->photo);
1883         if(pic) {
1884                 tgl_do_load_photo(TLS, pic ,&on_buddy_pic_loaded,U);
1885         }
1886 }
1887
1888 #if 0
1889 void on_chat_history_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1890 {
1891         tg_engine_data_s *tg_data = TLS->callback_data;
1892         if (!tg_data)
1893                 return;
1894
1895         for (int i = 0; i < size; i++) {
1896                 struct tgl_message* message = list[i];
1897                 if (message->service || message->from_id.id == tg_data->id.id) {
1898                         continue;
1899                 }
1900                 Eina_Bool ret = insert_buddy_msg_to_db(message);
1901                 if (ret) {
1902                         tg_msg_receive(s_info.TLS, message);
1903                 }
1904         }
1905         tg_data->current_chat_index = tg_data->current_chat_index + 1;
1906         if (tg_data->chat_list && (tg_data->current_chat_index < eina_list_count(tg_data->chat_list))) {
1907                 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
1908                 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_chat_history_received, UC);
1909         } else {
1910                 tg_data->current_chat_index = 0;
1911         }
1912 }
1913
1914 static Eina_Bool on_load_chat_history_requested(void *data)
1915 {
1916         struct tgl_state *TLS = data;
1917         tg_engine_data_s *tg_data = TLS->callback_data;
1918         if (TLS && tg_data && tg_data->chat_list && eina_list_count(tg_data->chat_list) > 0) {
1919                 tg_data->current_chat_index = 0;
1920                 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
1921                 if (UC) {
1922                         tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_chat_history_received, UC);
1923                 }
1924         }
1925         return ECORE_CALLBACK_CANCEL;
1926 }
1927
1928 void on_buddy_history_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1929 {
1930         tg_engine_data_s *tg_data = TLS->callback_data;
1931         for (int i = 0; i < size; i++) {
1932                 struct tgl_message* message = list[i];
1933                 if (message->service || message->from_id.id == tg_data->id.id) {
1934                         continue;
1935                 }
1936                 Eina_Bool ret = insert_buddy_msg_to_db(message);
1937                 if (ret) {
1938                         tg_msg_receive(s_info.TLS, message);
1939                 }
1940         }
1941         tg_data->current_buddy_index = tg_data->current_buddy_index + 1;
1942         if (tg_data->buddy_list && (tg_data->current_buddy_index < eina_list_count(tg_data->buddy_list))) {
1943                 tgl_peer_t* UC = eina_list_nth(tg_data->buddy_list, tg_data->current_buddy_index);
1944                 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_buddy_history_received, UC);
1945         } else {
1946                 tg_data->current_buddy_index = 0;
1947                 ecore_timer_add(5, on_load_chat_history_requested, TLS);
1948         }
1949 }
1950
1951 static Eina_Bool on_load_buddy_history_requested(void *data)
1952 {
1953         struct tgl_state *TLS = data;
1954         tg_engine_data_s *tg_data = TLS->callback_data;
1955         if (TLS && tg_data && tg_data->buddy_list && eina_list_count(tg_data->buddy_list) > 0) {
1956                 tg_data->current_buddy_index = 0;
1957                 tgl_peer_t* UC = eina_list_nth(tg_data->buddy_list, tg_data->current_buddy_index);
1958                 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_buddy_history_received, UC);
1959         }
1960         return ECORE_CALLBACK_CANCEL;
1961 }
1962 #endif
1963
1964 #if 0
1965 static Eina_Bool send_login_activated_response(void *data)
1966 {
1967         struct tgl_state *TLS = data;
1968         if (TLS) {
1969                 tg_engine_data_s *tg_data = TLS->callback_data;
1970                 send_response_for_server_connection_status(tg_data, tg_data->is_login_activated);
1971         }
1972         return ECORE_CALLBACK_CANCEL;
1973 }
1974
1975
1976 static Eina_Bool send_chat_loading_is_done_response(void *data)
1977 {
1978         struct tgl_state *TLS = data;
1979         if (TLS) {
1980                 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1981                 ecore_timer_add(3, send_login_activated_response, TLS);
1982         }
1983         return ECORE_CALLBACK_CANCEL;
1984 }
1985 #endif
1986
1987 void on_offline_chat_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1988 {
1989         tg_engine_data_s *tg_data = TLS->callback_data;
1990         for (int i = size - 1; i >= 0; i--) {
1991                 struct tgl_message* message = list[i];
1992                 if (message->service || message->from_id.id == tg_data->id.id) {
1993                         continue;
1994                 }
1995                 /*
1996                 Eina_Bool ret = insert_buddy_msg_to_db(message);
1997                 if (ret) {
1998                         tg_msg_receive(s_info.TLS, message);
1999                 }
2000                 */
2001                 tg_msg_receive(s_info.TLS, message);
2002         }
2003 }
2004
2005 static Eina_Bool on_load_offline_messages(void *data)
2006 {
2007         struct tgl_state *TLS = data;
2008         if (TLS) {
2009                 tg_engine_data_s *tg_data = TLS->callback_data;
2010                 if (!tg_data->is_first_time_registration) {
2011                         if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
2012                                 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
2013                                         tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
2014                                         struct tgl_message *last_msg = UC->last;
2015                                         if (last_msg) {
2016                                                 // check last message in message table
2017                                                 char* msg_table = get_table_name_from_number(UC->id.id);
2018                                                 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
2019                                                 if (!org_last_msg) {
2020                                                         tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
2021                                                 } else {
2022                                                         if (org_last_msg->message) {
2023                                                                 free(org_last_msg->message);
2024                                                         }
2025                                                         free(org_last_msg);
2026                                                 }
2027                                                 free(msg_table);
2028                                         }
2029                                 }
2030                         }
2031                 }
2032                 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
2033                         for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
2034                                 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
2035                                 char* msg_table = get_table_name_from_number(UC->id.id);
2036                                 create_buddy_msg_table(msg_table);
2037                                 delete_all_messages_from_chat(UC->id.id, UC->id.type);
2038                                 free(msg_table);
2039                         }
2040                 }
2041         }
2042         return ECORE_CALLBACK_CANCEL;
2043 }
2044
2045
2046 extern void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
2047
2048 static Eina_Bool on_async_peer_info_requested(void *data)
2049 {
2050         struct tgl_state *TLS = data;
2051         if (TLS) {
2052                 tg_engine_data_s *tg_data = TLS->callback_data;
2053                 tg_data->current_chat_index = tg_data->current_chat_index + 1;
2054                 if (tg_data->current_chat_index < eina_list_count(tg_data->chat_list)) {
2055                         tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2056                         if (UC) {
2057                                 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2058                         }
2059                 } else {
2060                         send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2061                         ecore_timer_add(5, on_send_unsent_messages_requested, TLS);
2062                 }
2063         }
2064         return ECORE_CALLBACK_CANCEL;
2065 }
2066
2067 void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
2068 {
2069         char *msg_table;
2070
2071         if (!chat_info) {
2072                 // go for next chat
2073                 goto end;
2074         }
2075         if (chat_info->flags == 144) {
2076                 // go for next chat
2077                 goto end;
2078         }
2079         msg_table = get_table_name_from_number(chat_info->id.id);
2080         create_buddy_msg_table(msg_table);
2081
2082         if (chat_info->admin_id > 0) {
2083                 set_date_item_to_table(msg_table, chat_info->date);
2084                 tgl_peer_id_t admin_id;
2085                 admin_id.id = chat_info->admin_id;
2086                 admin_id.type = TGL_PEER_USER;
2087
2088                 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
2089                 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2090                 char* creator_name = (char*)malloc(msg_len);
2091                 strcpy(creator_name, UC->user.first_name);
2092                 strcat(creator_name, " created the group");
2093                 struct tgl_message msg;
2094
2095                 msg.to_id = chat_info->id;
2096                 msg.from_id = admin_id;
2097                 msg.id = chat_info->id.id;
2098                 msg.message = creator_name;
2099                 msg.message_len = msg_len;
2100                 msg.unread = 0;
2101                 msg.date = chat_info->date;
2102                 msg.media.type = tgl_message_media_none;
2103                 msg.service = 1;
2104                 msg.out = 0;
2105
2106                 insert_buddy_msg_to_db(&msg);
2107                 free(creator_name);
2108         }
2109
2110         free(msg_table);
2111         if (chat_info->user_list) {
2112                 for (int i = 0; i < chat_info->user_list_size; i++) {
2113                         int user_id = chat_info->user_list[i].user_id;
2114                         Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
2115                         char* tb_name = get_table_name_from_number(user_id);
2116                         create_buddy_msg_table(tb_name);
2117                         if (!is_present_in_db) {
2118                                 // add to buddy table
2119                                 tgl_peer_id_t from_id;
2120                                 from_id.id = user_id;
2121                                 from_id.type = TGL_PEER_USER;
2122                                 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
2123                         }
2124                         free(tb_name);
2125                 }
2126         } else {
2127
2128         }
2129
2130         insert_chat_info_to_db(chat_info, NULL);
2131
2132         struct tgl_photo *pic = &(chat_info->photo);
2133         if(pic) {
2134                 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
2135         }
2136
2137 end:
2138         ecore_timer_add(1, on_async_peer_info_requested, TLS);
2139         return;
2140 }
2141
2142
2143 void on_contacts_and_chats_loaded(struct tgl_state *TLS, void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[])
2144 {
2145         tg_engine_data_s *tg_data = TLS->callback_data;
2146         if (tg_data->chat_list) {
2147                 eina_list_free(tg_data->chat_list);
2148                 tg_data->chat_list = NULL;
2149         }
2150         if (tg_data->buddy_list) {
2151                 eina_list_free(tg_data->buddy_list);
2152                 tg_data->buddy_list = NULL;
2153         }
2154         if (tg_data->peer_list) {
2155                 eina_list_free(tg_data->peer_list);
2156                 tg_data->peer_list = NULL;
2157         }
2158         for (int i = size - 1; i >= 0; i--) {
2159                 tgl_peer_t* UC = tgl_peer_get(TLS, peers[i]);
2160         // user exited from chat
2161                 if(UC->flags == 144) {
2162                         continue;
2163                 }
2164                 tg_data->peer_list = eina_list_append(tg_data->peer_list, UC);
2165                 // insert into peer table
2166                 switch (tgl_get_peer_type(peers[i])) {
2167                         case TGL_PEER_USER:
2168                                 tg_data->buddy_list = eina_list_append(tg_data->buddy_list, UC);
2169
2170                                 // check peer exists in peer table / buddy table
2171                                 Eina_Bool is_buddy_present = is_user_present_buddy_table(UC->id.id);
2172                                 if (!is_buddy_present) {
2173                                         struct tgl_user* buddy = &(UC->user);
2174                                         if (buddy) {
2175                                                 char* msg_table = get_table_name_from_number(buddy->id.id);
2176                                                 create_buddy_msg_table(msg_table);
2177                                                 free(msg_table);
2178
2179                                                 buddy->is_unknown = 1;
2180                                                 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2181                                                 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 1);
2182                                         }
2183                                 }
2184                                 break;
2185                         case TGL_PEER_CHAT:
2186
2187                                 tg_data->chat_list = eina_list_append(tg_data->chat_list, UC);
2188                                 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 0);
2189
2190                                 break;
2191                         case TGL_PEER_ENCR_CHAT:
2192                                 // To-Do
2193                                 break;
2194                         default:
2195                                 break;
2196                 }
2197
2198 #if 0
2199                 if (!tg_data->is_first_time_registration) {
2200                         struct tgl_message *last_msg = UC->last;
2201                         if (last_msg) {
2202                                 // check last message in message table
2203                                 char* msg_table = get_table_name_from_number(UC->id.id);
2204
2205                                 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
2206
2207                                 if (!org_last_msg) {
2208                                         tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
2209                                 } else {
2210                                         if (org_last_msg->message) {
2211                                                 free(org_last_msg->message);
2212                                         }
2213                                         free(org_last_msg);
2214                                 }
2215
2216                                 free(msg_table);
2217                         }
2218                 }
2219
2220                 char* msg_table = get_table_name_from_number(UC->id.id);
2221                 create_buddy_msg_table(msg_table);
2222                 delete_all_messages_from_chat(UC->id.id, UC->id.type);
2223                 free(msg_table);
2224 #endif
2225         }
2226 #if 0
2227         ecore_timer_add(3, on_send_unsent_messages_requested, TLS);
2228         send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2229 #endif
2230
2231         if ((tg_data->chat_list == NULL) || (eina_list_count(tg_data->chat_list) <= 0)) {
2232                 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2233                 ecore_timer_add(5, on_send_unsent_messages_requested, TLS);
2234         } else {
2235                 // load chat info one by one.
2236                 tg_data->current_chat_index = 0;
2237                 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2238                 if (UC) {
2239                         tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2240                 }
2241         }
2242 }
2243
2244 void on_contacts_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[])
2245 {
2246         //tg_engine_data_s *tg_data = TLS->callback_data;
2247         for (int i = size - 1; i >= 0; i--) {
2248                 struct tgl_user *buddy = contacts[i];
2249                 char* msg_table = get_table_name_from_number(buddy->id.id);
2250                 create_buddy_msg_table(msg_table);
2251                 free(msg_table);
2252
2253                 if (buddy->id.id == 333000 || buddy->id.id == 777000) {
2254                         buddy->is_unknown = 1;
2255                 } else {
2256                         buddy->is_unknown = 0;
2257                 }
2258                 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2259                 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
2260                 if (UC) {
2261                         insert_peer_into_database(UC, 0, 0, 0);
2262                 }
2263         }
2264
2265         // inform client that contact loading is done.
2266         for (int i = size - 1; i >= 0; i--) {
2267                 struct tgl_user *buddy = contacts[i];
2268                 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2269         }
2270
2271         tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2272
2273 }
2274
2275 void add_contacts_to_account(struct tgl_state *TLS)
2276 {
2277         tg_engine_data_s *tg_data = TLS->callback_data;
2278         if(sc_db_utils_connect())
2279         {
2280                 Eina_List* contact_list = get_contact_list_from_device_db();
2281                 sc_db_utils_disconnect();
2282
2283                 if (!contact_list || eina_list_count(contact_list) <= 0) {
2284                         // no contacts avilable. empty contact list.
2285                         //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2286                         // sandeep
2287                         tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2288                         if (contact_list) {
2289                                 eina_list_free(contact_list);
2290                         }
2291                         return;
2292                 }
2293                 int size = eina_list_count(contact_list);
2294                 if (size > 0) {
2295                         add_contacts_to_user(tg_data, size, contact_list);
2296                 } else {
2297                         eina_list_free(contact_list);
2298                         // sandeep
2299                         //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2300                         tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2301                 }
2302         }
2303 }
2304
2305 void on_user_info_loaded(struct tgl_state *TLS, void *extra, int success, struct tgl_user *buddy)
2306 {
2307         tg_engine_data_s *tg_data = TLS->callback_data;
2308
2309         tg_data->id.id = buddy->id.id;
2310         tg_data->id.type = buddy->id.type;
2311
2312         struct tgl_photo* pic = &(buddy->photo);
2313         if(pic) {
2314                 tgl_do_load_photo(TLS, pic ,&on_buddy_pic_loaded, buddy);
2315         }
2316
2317         buddy->is_unknown = 0;
2318         init_insert_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2319
2320 #if 0
2321         if (tg_data->is_first_time_registration) {
2322                 // send contact list to add friends.
2323                 //send_add_contacts_request(tg_data);
2324                 add_contacts_to_account(TLS);
2325         } else {
2326                 // sandeep
2327                 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2328                 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2329         }
2330 #else
2331         add_contacts_to_account(TLS);
2332 #endif
2333 }
2334
2335 void on_message_sent_to_buddy(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *message)
2336 {
2337         tg_engine_data_s *tg_data;
2338         struct tgl_message* org_msg = (struct tgl_message*)callback_extra;
2339         tg_data = TLS->callback_data;
2340
2341         if (success && message) {
2342                 tgl_peer_t* UC = tgl_peer_get(TLS, message->to_id);
2343                 if (UC) {
2344                         message->msg_state = TG_MESSAGE_STATE_SENT;
2345                         char* tb_name = get_table_name_from_number(message->to_id.id);
2346                         update_msg_into_db(message, tb_name, org_msg->id);
2347
2348                         // delete message from unsent db
2349                         delete_message_from_unsent_db(org_msg->id);
2350                         delete_media_from_unsent_db(org_msg->id);
2351
2352                         if (message->media.type == tgl_message_media_photo || message->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2353                                 update_sent_media_info_in_db(message, (long long)org_msg->id);
2354                         }
2355                         send_message_sent_to_buddy_response(tg_data, message->to_id.id, message->id, tb_name, EINA_TRUE, tgl_get_peer_type(message->to_id));
2356                         free(tb_name);
2357
2358                         if (message->media.type != tgl_message_media_none && (message->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
2359                                 //tgl_do_load_document_thumb(TLS, &(message->media.document), on_video_thumb_loaded, message);
2360                         }
2361
2362                 }
2363         } else {
2364                 if (org_msg) {
2365                         org_msg->msg_state = TG_MESSAGE_STATE_FAILED;
2366                         char* tb_name = get_table_name_from_number(org_msg->to_id.id);
2367                         update_msg_into_db(org_msg, tb_name, org_msg->id);
2368                         if (org_msg->media.type == tgl_message_media_photo || org_msg->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2369                                 if (org_msg->media.type == tgl_message_media_photo) {
2370                                         org_msg->media.photo.sizes_num = 0;
2371                                         org_msg->media.photo.sizes = NULL;
2372                                 }
2373                                 update_sent_media_info_in_db(org_msg, (long long)org_msg->id);
2374                         }
2375                         send_message_sent_to_buddy_response(tg_data, org_msg->to_id.id, org_msg->id, tb_name, EINA_FALSE, tgl_get_peer_type(org_msg->to_id));
2376                         free(tb_name);
2377                 }
2378         }
2379         if (org_msg) {
2380                 if (org_msg->message) {
2381                         free(org_msg->message);
2382                 }
2383                 free(org_msg);
2384         }
2385 }
2386
2387 void on_image_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2388 {
2389         tg_engine_data_s *tg_data = TLS->callback_data;
2390         struct tgl_photo* photo_prop = (struct tgl_photo*)callback_extra;
2391         long long media_id = photo_prop->id;
2392         int buddy_id = photo_prop->user_id;
2393         int to_id = photo_prop->to_peer_id;
2394         if (success) {
2395                 if(photo_prop && filename) {
2396                         update_receive_media_info_in_db(media_id, filename);
2397                         //send response to application
2398                         send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, photo_prop->caption);
2399                         free(photo_prop);
2400                 }
2401         } else {
2402                 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2403         }
2404 }
2405
2406 void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2407 {
2408         tg_engine_data_s *tg_data = TLS->callback_data;
2409         struct tgl_document* doc_prop = (struct tgl_document*)callback_extra;
2410         long long media_id = doc_prop->id;
2411         int buddy_id = doc_prop->user_id;
2412         int to_id = doc_prop->to_peer_id;
2413         if (success) {
2414                 if(doc_prop && filename) {
2415                         update_receive_media_info_in_db(media_id, filename);
2416                         //send response to application
2417                         send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, doc_prop->caption);
2418                 }
2419         } else {
2420                 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2421         }
2422
2423         if (doc_prop) {
2424                 if (doc_prop->caption) {
2425                         free(doc_prop->caption);
2426                 }
2427                 free(doc_prop);
2428         }
2429
2430 }
2431
2432 void free_contact_data(Eina_List *contact_data)
2433 {
2434         if (contact_data) {
2435                 for (int i = 0; i < eina_list_count(contact_data); i++) {
2436                         contact_data_s* contact = eina_list_nth(contact_data, i);
2437                         if (contact) {
2438                                 if (contact->display_name) {
2439                                         free(contact->display_name);
2440                                         contact->display_name = NULL;
2441                                 }
2442                                 if (contact->first_name) {
2443                                         free(contact->first_name);
2444                                         contact->first_name = NULL;
2445                                 }
2446                                 if (contact->last_name) {
2447                                         free(contact->last_name);
2448                                         contact->last_name = NULL;
2449                                 }
2450                                 if (contact->phone_number) {
2451                                         free(contact->phone_number);
2452                                         contact->phone_number = NULL;
2453                                 }
2454                         }
2455                         free(contact);
2456                 }
2457                 eina_list_free(contact_data);
2458         }
2459 }
2460
2461 void on_contact_added(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[])
2462 {
2463         tg_engine_data_s* data = callback_extra;
2464
2465         data->current_index++;
2466
2467         if (data->current_index < eina_list_count(data->contact_list_to_add)) {
2468                 contact_data_s* contact = eina_list_nth(data->contact_list_to_add, data->current_index);
2469
2470                 if (contact) {
2471                         char *first_name = contact->first_name;
2472                         char *last_name = contact->last_name;
2473                         char *phone_number = contact->phone_number;
2474
2475                         if (!first_name) {
2476                                 first_name = contact->display_name;
2477                                 if (!first_name) {
2478                                         first_name = "";
2479                                 }
2480                         }
2481
2482                         if (!last_name) {
2483                                 last_name = "";
2484                         }
2485
2486                         if (first_name && last_name && phone_number) {
2487                                 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, data);
2488                         } else {
2489                                 on_contact_added(tgl_engine_get_TLS(), data, 0, 0, NULL);
2490                         }
2491                 }
2492
2493         } else {
2494                 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2495                 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2496                 free_contact_data(data->contact_list_to_add);
2497                 data->contact_list_to_add = NULL;
2498         }
2499 }
2500
2501 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2502 {
2503         tg_engine_data_s *tg_data = TLS->callback_data;
2504         if (!success) {
2505                 // send fail notification
2506         } else {
2507                 // send success notofication
2508                 if (M) {
2509                         if (M->action.type == tgl_message_action_chat_create) {
2510
2511                         } else if (M->action.type == tgl_message_action_chat_edit_title) {
2512
2513                         } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2514
2515                                 char* msg_table = get_table_name_from_number(M->to_id.id);
2516                                 create_buddy_msg_table(msg_table);
2517                                 int msg_id = insert_current_date_to_table(msg_table);
2518
2519                                 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2520                                 int msg_len = strlen(UC->user.first_name) + strlen(" changed profile photo") + 1;
2521                                 char* creator_name = (char*)malloc(msg_len);
2522                                 strcpy(creator_name, UC->user.first_name);
2523                                 strcat(creator_name, " changed profile photo");
2524
2525
2526                                 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2527                                 int cur_time = time(NULL);
2528                                 M->id = cur_time;
2529                                 M->message = creator_name;
2530                                 M->message_len = msg_len;
2531                                 M->unread = 1;
2532                                 M->date = cur_time;
2533                                 insert_buddy_msg_to_db(M);
2534                                 free(creator_name);
2535                                 free(msg_table);
2536                                 struct tgl_photo *pic = &(M->action.photo);
2537                                 if(pic) {
2538                                         tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2539                                         struct tgl_chat *chat_info = &(UC->chat);
2540                                         tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded, chat_info);
2541                                 }
2542
2543
2544                         } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2545
2546                         } else if (M->action.type == tgl_message_action_chat_add_user) {
2547
2548                         } else if (M->action.type == tgl_message_action_chat_delete_user) {
2549
2550                         }
2551                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2552
2553
2554                 }
2555         }
2556
2557 }
2558
2559 void on_new_group_created(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2560 {
2561         tg_engine_data_s *tg_data = TLS->callback_data;
2562         if (!success) {
2563                 // send fail notification
2564         } else {
2565                 // send success notofication
2566                 if (M) {
2567                         if (M->action.type == tgl_message_action_chat_create) {
2568                                 char* msg_table = get_table_name_from_number(M->to_id.id);
2569                                 create_buddy_msg_table(msg_table);
2570
2571
2572                                 int msg_id = insert_current_date_to_table(msg_table);
2573                                 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2574
2575
2576                                 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2577                                 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2578                                 char* creator_name = (char*)malloc(msg_len);
2579                                 strcpy(creator_name, UC->user.first_name);
2580                                 strcat(creator_name, " created the group");
2581
2582
2583
2584                                 int cur_time = time(NULL);
2585                                 M->id = M->to_id.id;
2586                                 M->message = creator_name;
2587                                 M->message_len = msg_len;
2588                                 M->unread = 1;
2589                                 M->date = cur_time;
2590
2591                                 insert_buddy_msg_to_db(M);
2592                                 free(creator_name);
2593                                 free(msg_table);
2594                                 tgl_peer_t* chat_UC = tgl_peer_get(TLS, M->to_id);
2595                                 chat_UC->chat.date = M->date;
2596                                 insert_chat_info_to_db(&(chat_UC->chat), NULL);
2597                                 chat_UC->last = M;
2598                                 insert_peer_into_database(chat_UC, 0, 0, 0);
2599
2600                                 if (tg_data->new_group_icon) {
2601                                         tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2602                                         struct tgl_chat *chat_info = &(UC->chat);
2603                                         tgl_do_set_chat_photo(TLS, chat_info->id, tg_data->new_group_icon, on_new_group_icon_loaded, chat_info);
2604                                 }
2605
2606
2607                         } else if (M->action.type == tgl_message_action_chat_edit_title) {
2608
2609                         } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2610
2611                         } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2612
2613                         } else if (M->action.type == tgl_message_action_chat_add_user) {
2614
2615                         } else if (M->action.type == tgl_message_action_chat_delete_user) {
2616
2617                         }
2618                         send_new_group_added_response(tg_data, M->to_id.id);
2619                 }
2620         }
2621 }
2622
2623 void on_set_profile_picture_response_received(struct tgl_state *TLS, void *callback_extra, int success)
2624 {
2625         tg_engine_data_s *tg_data = TLS->callback_data;
2626         char *file_path = callback_extra;
2627         if (success) {
2628                 // update db
2629                 update_buddy_pic_db(file_path, USER_INFO_TABLE_NAME, tg_data->id.id);
2630                 update_buddy_pic_db(file_path, BUDDY_INFO_TABLE_NAME, tg_data->id.id);
2631                 send_self_profile_picture_updated_response(tg_data, file_path, EINA_TRUE);
2632         } else {
2633                 send_self_profile_picture_updated_response(tg_data, file_path, EINA_FALSE);
2634         }
2635         if (file_path) {
2636                 free(file_path);
2637         }
2638 }
2639 void set_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2640 {
2641         if (file_path) {
2642                 char *org_path = strdup(file_path);
2643                 tgl_do_set_profile_photo(tgl_engine_get_TLS(), (char*)file_path, on_set_profile_picture_response_received, org_path);
2644         }
2645 }
2646
2647 void on_set_new_chat_title_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2648 {
2649         if (success) {
2650                 char *type_of_change = NULL;
2651                 if (M && M->action.type == tgl_message_action_chat_edit_title) {
2652                         type_of_change = strdup("edit_title");
2653                         tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2654                         int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
2655                         char* creator_name = (char*)malloc(msg_len);
2656                         strcpy(creator_name, UC->user.first_name);
2657                         strcat(creator_name, " changed the chat title");
2658
2659                         int cur_time = time(NULL);
2660                         M->id = cur_time;
2661                         M->message = creator_name;
2662                         M->message_len = msg_len;
2663                         M->unread = 1;
2664                         M->date = cur_time;
2665                         insert_buddy_msg_to_db(M);
2666                         free(creator_name);
2667                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2668                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2669                 }
2670         } else {
2671                 tg_engine_data_s *tg_data = TLS->callback_data;
2672                 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2673                 send_group_chat_rename_response(tg_data, chat_info->id.id, EINA_FALSE);
2674         }
2675 }
2676
2677 void set_group_chat_new_title(tg_engine_data_s *tg_data, int buddy_id, const char *new_title)
2678 {
2679         if (new_title) {
2680                 tgl_peer_id_t peer_id;
2681                 peer_id.id = buddy_id;
2682                 peer_id.type = TGL_PEER_CHAT;
2683
2684                 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2685                 struct tgl_chat *chat_info = &(UC->chat);
2686                 tgl_do_rename_chat(tgl_engine_get_TLS(), chat_info->id, (char*)new_title, on_set_new_chat_title_response_received, chat_info);
2687         }
2688 }
2689
2690 void on_new_buddy_added_to_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2691 {
2692         if (success) {
2693                 char *type_of_change = NULL;
2694                 if (M && M->action.type == tgl_message_action_chat_add_user) {
2695                         type_of_change = strdup("add_user");
2696                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
2697
2698                         tgl_peer_id_t added_id;
2699                         added_id.id = M->action.user;
2700                         added_id.type = TGL_PEER_USER;
2701
2702                         tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2703                         char* new_user_name = replace(added_UC->print_name, '_', " ");
2704                         int msg_len = strlen(UC->user.first_name) + strlen(" added ") + strlen(new_user_name) + 1;
2705                         char* creator_name = (char*)malloc(msg_len);
2706                         strcpy(creator_name, UC->user.first_name);
2707                         strcat(creator_name, " added ");
2708                         strcat(creator_name, new_user_name);
2709                         free(new_user_name);
2710
2711                         int cur_time = time(NULL);
2712                         M->id = cur_time;
2713                         M->message = creator_name;
2714                         M->message_len = msg_len;
2715                         M->unread = 1;
2716                         M->date = cur_time;
2717                         insert_buddy_msg_to_db(M);
2718                         free(creator_name);
2719                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2720                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2721                 }
2722         } else {
2723                 tg_engine_data_s *tg_data = TLS->callback_data;
2724                 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2725                 send_group_chat_new_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2726         }
2727 }
2728
2729 void set_group_chat_add_new_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2730 {
2731         tgl_peer_id_t chat_id;
2732         chat_id.id = s_chat_id;
2733         chat_id.type = TGL_PEER_CHAT;
2734
2735         tgl_peer_id_t buddy_id;
2736         buddy_id.id = s_buddy_id;
2737         buddy_id.type = TGL_PEER_USER;
2738
2739         tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2740         struct tgl_chat *chat_info = &(UC->chat);
2741         tgl_do_add_user_to_chat(tgl_engine_get_TLS(), chat_id, buddy_id, 100, on_new_buddy_added_to_chat_response_received, chat_info);
2742 }
2743
2744
2745 void on_buddy_removed_from_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2746 {
2747         if (success) {
2748                 char *type_of_change = NULL;
2749                 if (M && M->action.type == tgl_message_action_chat_delete_user) {
2750                         type_of_change = strdup("delete_user");
2751                         tgl_peer_t* UC = tgl_peer_get(TLS,  M->from_id);
2752                         tgl_peer_id_t added_id;
2753                         added_id.id = M->action.user;
2754                         added_id.type = TGL_PEER_USER;
2755
2756                         tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2757                         char* new_user_name = replace(added_UC->print_name, '_', " ");
2758                         int msg_len = strlen(UC->user.first_name) + strlen(" removed ") + strlen(new_user_name) + 1;
2759                         char* creator_name = (char*)malloc(msg_len);
2760                         strcpy(creator_name, UC->user.first_name);
2761                         strcat(creator_name, " removed ");
2762                         strcat(creator_name, new_user_name);
2763                         free(new_user_name);
2764                         int cur_time = time(NULL);
2765                         M->id = cur_time;
2766                         M->message = creator_name;
2767                         M->message_len = msg_len;
2768                         M->unread = 1;
2769                         M->date = cur_time;
2770                         insert_buddy_msg_to_db(M);
2771                         free(creator_name);
2772                         send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2773                         tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2774                 }
2775         } else {
2776                 tg_engine_data_s *tg_data = TLS->callback_data;
2777                 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2778                 send_group_chat_delete_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2779         }
2780 }
2781
2782 void set_group_chat_remove_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2783 {
2784         tgl_peer_id_t chat_id;
2785         chat_id.id = s_chat_id;
2786         chat_id.type = TGL_PEER_CHAT;
2787
2788         tgl_peer_id_t buddy_id;
2789         buddy_id.id = s_buddy_id;
2790         buddy_id.type = TGL_PEER_USER;
2791
2792         tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2793         struct tgl_chat *chat_info = &(UC->chat);
2794         tgl_do_del_user_from_chat(tgl_engine_get_TLS(), chat_id, buddy_id, on_buddy_removed_from_chat_response_received, chat_info);
2795 }
2796
2797 void set_group_chat_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2798 {
2799         if (file_path) {
2800                 tgl_peer_id_t peer_id;
2801                 peer_id.id = buddy_id;
2802                 peer_id.type = TGL_PEER_CHAT;
2803
2804                 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2805                 struct tgl_chat *chat_info = &(UC->chat);
2806                 tgl_do_set_chat_photo(tgl_engine_get_TLS(), chat_info->id, (char*)file_path, on_new_group_icon_loaded, chat_info);
2807         }
2808 }
2809
2810 void on_set_username_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2811 {
2812         tg_engine_data_s *tg_data = TLS->callback_data;
2813         char *org_username = callback_extra;
2814         if (success) {
2815                 // update db
2816                 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2817                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2818                 send_self_user_name_updated_response(tg_data, org_username, EINA_TRUE);
2819         } else {
2820                 send_self_user_name_updated_response(tg_data, org_username, EINA_FALSE);
2821         }
2822         if (org_username) {
2823                 free(org_username);
2824         }
2825 }
2826
2827 void set_user_name(tg_engine_data_s *tg_data, int buddy_id, const char *username)
2828 {
2829         if (username) {
2830                 char *org_username = strdup(username);
2831                 tgl_do_set_username(tgl_engine_get_TLS(), username, on_set_username_response_received, org_username);
2832         }
2833 }
2834
2835 void on_profile_name_changed(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2836 {
2837         tg_engine_data_s *tg_data = callback_extra;
2838         if (success) {
2839                 // update db
2840                 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2841                 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2842                 send_self_profile_name_updated_response(tg_data, buddy->first_name, buddy->last_name, EINA_TRUE);
2843         } else {
2844                 send_self_profile_name_updated_response(tg_data, "", "", EINA_FALSE);
2845         }
2846 }
2847
2848 void update_user_display_name(tg_engine_data_s *tg_data, int buddy_id, const char *first_name, const char *last_name)
2849 {
2850         if (first_name && last_name) {
2851                 tgl_do_set_profile_name(tgl_engine_get_TLS(), first_name, last_name, on_profile_name_changed, tg_data);
2852         }
2853 }
2854
2855 void create_new_group(tg_engine_data_s *tg_data, Eina_List* buddy_ids, const char *group_name, const char *group_icon)
2856 {
2857         if (!buddy_ids || ! group_name) {
2858                 return;
2859         }
2860         int users_num = eina_list_count(buddy_ids);
2861         static tgl_peer_id_t ids[1024];
2862         static char _group_icon[1024];
2863         int i;
2864         for (i = 0; i < users_num; i++) {
2865                 char *buddy_id_str = (char *)eina_list_nth(buddy_ids, i);
2866                 int buddy_id = atoi(buddy_id_str);
2867                 ids[i].id = buddy_id;
2868                 ids[i].type = TGL_PEER_USER;
2869         }
2870
2871         strncpy(_group_icon, group_icon, sizeof(_group_icon));
2872
2873         tgl_do_create_group_chat_ex(tgl_engine_get_TLS(), users_num, ids, group_name, on_new_group_created, (void *)_group_icon);
2874         tg_data->is_group_creation_requested = EINA_TRUE;
2875
2876         if (tg_data->new_group_icon) {
2877                 free(tg_data->new_group_icon);
2878         }
2879
2880         if (group_icon && strlen(group_icon) > 0) {
2881                 tg_data->new_group_icon = strdup(group_icon);
2882         } else {
2883                 tg_data->new_group_icon = NULL;
2884         }
2885
2886 }
2887
2888 void add_contacts_to_user(tg_engine_data_s *tg_data, int size, Eina_List* contact_list)
2889 {
2890         tg_data->contact_list_to_add = contact_list;
2891         contact_data_s* contact = eina_list_nth(contact_list, 0);
2892         if (contact) {
2893                 char *first_name = contact->first_name;
2894                 char *last_name = contact->last_name;
2895                 char *phone_number = contact->phone_number;
2896
2897                 tg_data->current_index = 0;
2898
2899                 if (!first_name) {
2900                         first_name = contact->display_name;
2901                         if (!first_name) {
2902                                 first_name = "";
2903                         }
2904                 }
2905
2906                 if (!last_name) {
2907                         last_name = "";
2908                 }
2909
2910                 if (first_name && last_name && phone_number) {
2911                         tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, tg_data);
2912                 } else {
2913                         on_contact_added(tgl_engine_get_TLS(), tg_data, 0, 0, NULL);
2914                 }
2915         }
2916 }
2917
2918 void media_download_request(tg_engine_data_s *tg_data, int buddy_id, long long media_id)
2919 {
2920         // get media details by mediaid
2921         struct tgl_media* img_details = get_media_details_from_db(media_id);
2922
2923         if(!img_details) {
2924                 send_media_download_completed_response(tg_data, -1, buddy_id, media_id, NULL, NULL);
2925                 return;
2926         } else {
2927
2928                 if (img_details->media_type == tgl_message_media_none) {
2929
2930                 } else if (img_details->media_type == tgl_message_media_photo) {
2931
2932                         struct tgl_photo* photo_prop = (struct tgl_photo*)malloc(sizeof(struct tgl_photo));
2933                         photo_prop->id = img_details->media_id;
2934                         photo_prop->access_hash = img_details->access_hash;
2935                         photo_prop->user_id = img_details->user_id;
2936                         photo_prop->date = img_details->date;
2937                         photo_prop->caption = img_details->caption;
2938                         photo_prop->geo.latitude = atof(img_details->latitude);
2939                         photo_prop->geo.longitude = atof(img_details->longitude);
2940                         photo_prop->sizes_num = img_details->sizes;
2941
2942                         photo_prop->sizes = talloc(sizeof(struct tgl_photo_size) * photo_prop->sizes_num);
2943                         int i;
2944                         for (i = 0; i < photo_prop->sizes_num; i++) {
2945
2946                                 if (i == 0) {
2947                                         photo_prop->sizes[i].w = img_details->photo_width1;
2948                                         photo_prop->sizes[i].h = img_details->photo_height1;
2949                                         photo_prop->sizes[i].size = img_details->photo_size1;
2950                                         if(img_details->photo_data1) {
2951                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data1);
2952                                         }
2953                                         if(img_details->photo_type1) {
2954                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type1);
2955                                         }
2956                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc1;
2957                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id1;
2958                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec1;
2959                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol1;
2960                                 } else if (i == 1) {
2961
2962                                         photo_prop->sizes[i].w = img_details->photo_width2;
2963                                         photo_prop->sizes[i].h = img_details->photo_height2;
2964                                         photo_prop->sizes[i].size = img_details->photo_size2;
2965                                         if(img_details->photo_data2) {
2966                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data2);
2967                                         }
2968                                         if(img_details->photo_type2) {
2969                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type2);
2970                                         }
2971                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc2;
2972                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id2;
2973                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec2;
2974                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol2;
2975
2976                                 } else if (i == 2) {
2977
2978                                         photo_prop->sizes[i].w = img_details->photo_width3;
2979                                         photo_prop->sizes[i].h = img_details->photo_height3;
2980                                         photo_prop->sizes[i].size = img_details->photo_size3;
2981                                         if(img_details->photo_data3) {
2982                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data3);
2983                                         }
2984                                         if(img_details->photo_type3) {
2985                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type3);
2986                                         }
2987                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc3;
2988                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id3;
2989                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec3;
2990                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol3;
2991
2992                                 } else if (i == 3) {
2993
2994                                         photo_prop->sizes[i].w = img_details->photo_width4;
2995                                         photo_prop->sizes[i].h = img_details->photo_height4;
2996                                         photo_prop->sizes[i].size = img_details->photo_size4;
2997                                         if(img_details->photo_data4) {
2998                                                 photo_prop->sizes[i].data = strdup(img_details->photo_data4);
2999                                         }
3000                                         if(img_details->photo_type4) {
3001                                                 photo_prop->sizes[i].type = strdup(img_details->photo_type4);
3002                                         }
3003                                         photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc4;
3004                                         photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id4;
3005                                         photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec4;
3006                                         photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol4;
3007
3008                                 } else {
3009
3010                                 }
3011                         }
3012                         photo_prop->to_peer_id = buddy_id;
3013                         tgl_do_load_photo(s_info.TLS, photo_prop ,&on_image_download_completed, photo_prop);
3014
3015                 } else if (img_details->media_type == tgl_message_media_document) {
3016                         struct tgl_document* doc_prop = (struct tgl_document*)malloc(sizeof(struct tgl_document));
3017                         doc_prop->id = img_details->media_id;;
3018                         doc_prop->access_hash = img_details->access_hash;
3019                         doc_prop->user_id = img_details->user_id;
3020                         doc_prop->date = img_details->date;
3021                         doc_prop->size = img_details->sizes;
3022                         doc_prop->mime_type = NULL;
3023                         doc_prop->dc_id = img_details->doc_dc;
3024                         doc_prop->to_peer_id = buddy_id;
3025
3026                         if (img_details->caption) {
3027                                 doc_prop->caption = strdup(img_details->caption);
3028                         } else {
3029                                 doc_prop->caption = NULL;
3030                         }
3031
3032
3033                         if (!(img_details->mime_type) || strlen(img_details->mime_type) <= 0) {
3034
3035                                 if (img_details->doc_type && strlen(img_details->doc_type) > 0) {
3036                                         if (strstr(img_details->doc_type, "video") != NULL) {
3037                                                 doc_prop->mime_type = strdup("video/mp4");
3038                                         } else if (strstr(img_details->doc_type, "audio") != NULL) {
3039                                                 doc_prop->mime_type = strdup("audio/wav");
3040                                         } else if (strstr(img_details->doc_type, "image/gif") != NULL) {
3041                                                 doc_prop->mime_type = strdup("image/gif");
3042                                         }
3043                                 }
3044                         } else {
3045                                 doc_prop->mime_type = img_details->mime_type;
3046                         }
3047
3048                         if (strstr(img_details->doc_type, "video") != NULL) {
3049                                 doc_prop->flags =  FLAG_DOCUMENT_VIDEO;
3050                         } else if (strstr(img_details->doc_type, "audio") != NULL) {
3051                                 doc_prop->flags =  FLAG_DOCUMENT_AUDIO;
3052                         } else if (strstr(img_details->doc_type, "image") != NULL) {
3053                                 doc_prop->flags =  FLAG_DOCUMENT_ANIMATED;
3054                         }
3055
3056                         tgl_do_load_document(s_info.TLS, doc_prop ,on_document_download_completed, doc_prop);
3057
3058
3059                 } else {
3060
3061                 }
3062
3063                 // delete image details
3064
3065                 if (img_details->caption) {
3066                         free(img_details->caption);
3067                 }
3068                 if (img_details->longitude) {
3069                         free(img_details->longitude);
3070                 }
3071                 if (img_details->latitude) {
3072                         free(img_details->latitude);
3073                 }
3074                 if (img_details->phone_no) {
3075                         free(img_details->phone_no);
3076                 }
3077                 if (img_details->first_name) {
3078                         free(img_details->first_name);
3079                 }
3080                 if (img_details->last_name) {
3081                         free(img_details->last_name);
3082                 }
3083                 if (img_details->file_path) {
3084                         free(img_details->file_path);
3085                 }
3086                 if (img_details->photo_type1) {
3087                         free(img_details->photo_type1);
3088                 }
3089                 if (img_details->photo_data1) {
3090                         free(img_details->photo_data1);
3091                 }
3092                 if (img_details->photo_type2) {
3093                         free(img_details->photo_type2);
3094                 }
3095                 if (img_details->photo_data2) {
3096                         free(img_details->photo_data2);
3097                 }
3098                 if (img_details->photo_type3) {
3099                         free(img_details->photo_type3);
3100                 }
3101                 if (img_details->photo_data3) {
3102                         free(img_details->photo_data3);
3103                 }
3104                 if (img_details->photo_type4) {
3105                         free(img_details->photo_type4);
3106                 }
3107                 if (img_details->photo_data4) {
3108                         free(img_details->photo_data4);
3109                 }
3110                 if (img_details->mime_type) {
3111                         free(img_details->mime_type);
3112                 }
3113                 if (img_details->doc_type) {
3114                         free(img_details->doc_type);
3115                 }
3116                 if (img_details->doc_thumb_path) {
3117                         free(img_details->doc_thumb_path);
3118                 }
3119
3120         }
3121 }
3122
3123 void on_mark_read_callback(struct tgl_state *TLS, void *callback_extra, int success)
3124 {
3125         // message read sent successfully. update to UI if needed.
3126 }
3127
3128
3129 void on_message_deleted_from_message_list(struct tgl_state *TLS, void *callback_extra, int success)
3130 {
3131         msg_list_container_s *msg_list_container = (msg_list_container_s*)callback_extra;
3132         tg_engine_data_s *tg_data = TLS->callback_data;
3133
3134         if (success && msg_list_container) {
3135                 // delete message from message table
3136                 char* tb_name = get_table_name_from_number(msg_list_container->buddy_id);
3137                 delete_message_from_table(tb_name, msg_list_container->current_message_id);
3138                 free(tb_name);
3139         }
3140
3141         if (msg_list_container && msg_list_container->message_ids) {
3142                 if (msg_list_container->current_index < eina_list_count(msg_list_container->message_ids)) {
3143                         msg_list_container->current_index = msg_list_container->current_index + 1;
3144                         msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3145                         tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3146                 } else {
3147                         eina_list_free(msg_list_container->message_ids);
3148                         free(msg_list_container);
3149                 }
3150         }
3151 }
3152
3153 void delete_all_messages_from_chat(int buddy_id, int type_of_chat)
3154 {
3155         tgl_peer_id_t chat_id;
3156         chat_id.id = buddy_id;
3157         chat_id.type = type_of_chat;
3158
3159         char* tb_name = get_table_name_from_number(buddy_id);
3160         //get all message ids from table.
3161         Eina_List *msg_ids = get_all_message_ids_from_table(tb_name);
3162         free(tb_name);
3163
3164         if (msg_ids && eina_list_count(msg_ids) > 0) {
3165                 msg_list_container_s *msg_list_container = (msg_list_container_s*)malloc(sizeof(msg_list_container_s));
3166                 msg_list_container->message_ids = msg_ids;
3167                 msg_list_container->buddy_id = buddy_id;
3168                 msg_list_container->current_index = 0;
3169                 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3170
3171                 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3172         }
3173
3174 }
3175
3176
3177 void send_do_mark_read_messages(int buddy_id, int type_of_chat)
3178 {
3179         tgl_peer_id_t chat_id;
3180         chat_id.id = buddy_id;
3181         chat_id.type = type_of_chat;
3182
3183         tgl_do_mark_read(s_info.TLS, chat_id, &on_mark_read_callback , (void*)(&chat_id));
3184 }
3185
3186
3187 void on_user_block_response(struct tgl_state *TLS, void *callback_extra, int success)
3188 {
3189         int buddy_id = (int)callback_extra;
3190         tg_engine_data_s *tg_data = TLS->callback_data;
3191         if (success) {
3192                 // update database
3193                 int blocked = 1;
3194                 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3195                 send_buddy_blocked_response(tg_data, buddy_id, EINA_TRUE);
3196         } else {
3197                 send_buddy_blocked_response(tg_data, buddy_id, EINA_FALSE);
3198         }
3199 }
3200
3201 void on_user_unblock_response(struct tgl_state *TLS, void *callback_extra, int success)
3202 {
3203         int buddy_id = (int)callback_extra;
3204         tg_engine_data_s *tg_data = TLS->callback_data;
3205         if (success) {
3206                 int blocked = 0;
3207                 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3208                 send_buddy_unblocked_response(tg_data, buddy_id, EINA_TRUE);
3209         } else {
3210                 send_buddy_unblocked_response(tg_data, buddy_id, EINA_FALSE);
3211         }
3212 }
3213
3214 void on_user_delete_response(struct tgl_state *TLS, void *callback_extra, int success)
3215 {
3216         int buddy_id = (int)callback_extra;
3217         tg_engine_data_s *tg_data = TLS->callback_data;
3218         if (success) {
3219                 // update database
3220                 // delete from peer table
3221                 // delete from buddy table
3222                 // delete chat items
3223 #if 0
3224                 //delete_chat_from_db(buddy_id);
3225                 //delete_buddy_from_db(buddy_id);
3226                 //char* msg_table = get_table_name_from_number(buddy_id);
3227                 //drop_table(msg_table);
3228                 //free(msg_table);
3229 #endif
3230                 int deleted = 1;
3231                 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3232                 send_buddy_deleted_response(tg_data, buddy_id, EINA_TRUE);
3233         } else {
3234                 send_buddy_deleted_response(tg_data, buddy_id, EINA_FALSE);
3235         }
3236 }
3237
3238
3239 void on_buddy_readded(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[])
3240 {
3241         int buddy_id = (int)callback_extra;
3242         tg_engine_data_s *tg_data = TLS->callback_data;
3243         if (success) {
3244                 int deleted = 0;
3245                 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3246                 send_buddy_readded_response(tg_data, buddy_id, EINA_TRUE);
3247         } else {
3248                 send_buddy_readded_response(tg_data, buddy_id, EINA_FALSE);
3249         }
3250 }
3251
3252 void on_new_buddy_added(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[])
3253 {
3254         tg_engine_data_s *tg_data = TLS->callback_data;
3255         if (success) {
3256                 struct tgl_user *buddy = users[0];
3257                 if (buddy) {
3258                         char* msg_table = get_table_name_from_number(buddy->id.id);
3259                         create_buddy_msg_table(msg_table);
3260                         free(msg_table);
3261
3262                         if (buddy->id.id == 333000 || buddy->id.id == 777000) {
3263                                 buddy->is_unknown = 1;
3264                         } else {
3265                                 buddy->is_unknown = 0;
3266                         }
3267                         init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
3268                         tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
3269                         if (UC) {
3270                                 insert_peer_into_database(UC, 0, 0, 0);
3271                         }
3272                         tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
3273
3274                         // send response to application
3275                         send_new_contact_added_response(tg_data, buddy->id.id, EINA_TRUE);
3276                 } else {
3277                         send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3278                 }
3279
3280         } else {
3281                 send_new_contact_added_response(tg_data, -1, EINA_TRUE);
3282         }
3283 }
3284
3285 void do_add_buddy(int buddy_id, char *first_name, char *last_name, char *phone_num)
3286 {
3287         if (!first_name) {
3288                 first_name = "";
3289         }
3290         if (!last_name) {
3291                 last_name = "";
3292         }
3293         if (!phone_num) {
3294                 phone_num = "";
3295         }
3296
3297         if (first_name && last_name && phone_num) {
3298                 if (buddy_id == -1) {
3299                         tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_new_buddy_added, (void*)(buddy_id));
3300                 } else {
3301                         tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_buddy_readded, (void*)(buddy_id));
3302                 }
3303         }
3304 }
3305
3306
3307 void logout_telegram(tg_engine_data_s *tg_data)
3308 {
3309
3310 }
3311
3312 void on_secret_chat_request_sent(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E)
3313 {
3314         int buddy_id = (int)callback_extra;
3315         tg_engine_data_s *tg_data = TLS->callback_data;
3316         if (success) {
3317
3318         } else {
3319
3320         }
3321 }
3322
3323 void request_for_secret_chat(int buddy_id)
3324 {
3325         tgl_peer_id_t peer_id;
3326         peer_id.id = buddy_id;
3327         peer_id.type = TGL_PEER_USER;
3328         tgl_do_create_secret_chat(s_info.TLS, peer_id, on_secret_chat_request_sent, (void*)(buddy_id));
3329 }
3330
3331 void do_delete_buddy(int buddy_id)
3332 {
3333         tgl_peer_id_t peer_id;
3334         peer_id.id = buddy_id;
3335         peer_id.type = TGL_PEER_USER;
3336         tgl_do_del_contact(s_info.TLS, peer_id, &on_user_delete_response , (void*)(buddy_id));
3337 }
3338
3339 void on_message_deleted(struct tgl_state *TLS, void *callback_extra, int success)
3340 {
3341         msg_container_s *msg_details = (msg_container_s*)callback_extra;
3342         tg_engine_data_s *tg_data = TLS->callback_data;
3343         if (success) {
3344                 // update database
3345                 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_TRUE);
3346         } else {
3347                 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_FALSE);
3348         }
3349 }
3350
3351 void do_delete_message(int buddy_id, int message_id)
3352 {
3353         msg_container_s *msg_details = (msg_container_s*)malloc(sizeof(msg_container_s));
3354         msg_details->buddy_id = buddy_id;
3355         msg_details->message_id = message_id;
3356         tgl_do_delete_msg(s_info.TLS, message_id, &on_message_deleted , (void*)(msg_details));
3357 }
3358
3359
3360 void do_block_buddy(int buddy_id)
3361 {
3362         tgl_peer_id_t peer_id;
3363         peer_id.id = buddy_id;
3364         peer_id.type = TGL_PEER_USER;
3365         tgl_do_block_user(s_info.TLS, peer_id, &on_user_block_response , (void*)(buddy_id));
3366 }
3367
3368 void do_unblock_buddy(int buddy_id)
3369 {
3370         tgl_peer_id_t peer_id;
3371         peer_id.id = buddy_id;
3372         peer_id.type = TGL_PEER_USER;
3373         tgl_do_unblock_user(s_info.TLS, peer_id, &on_user_unblock_response , (void*)(buddy_id));
3374 }
3375
3376 extern void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M);
3377 static Eina_Bool on_async_chat_deletion_requested(void *data)
3378 {
3379         Eina_List *sel_grp_chats = data;
3380         if (sel_grp_chats) {
3381                 tg_engine_data_s *tg_data = tgl_engine_get_TLS()->callback_data;
3382                 tg_data->current_group_chat_index = tg_data->current_group_chat_index + 1;
3383
3384                 if (tg_data->current_group_chat_index < eina_list_count(sel_grp_chats)) {
3385                         int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3386
3387                         tgl_peer_id_t chat_id;
3388                         chat_id.id = group_chat_id;
3389                         chat_id.type = TGL_PEER_CHAT;
3390
3391                         tgl_peer_id_t self_id = tg_data->id;
3392
3393                         tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3394                 } else {
3395                         send_selected_group_chats_deleted_response(tg_data);
3396                 }
3397         }
3398         return ECORE_CALLBACK_CANCEL;
3399 }
3400
3401
3402 void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3403 {
3404         Eina_List *sel_grp_chats = callback_extra;
3405         tg_engine_data_s *tg_data = TLS->callback_data;
3406         int chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3407
3408         if (success) {
3409                 // update database
3410                 // delete from peer table
3411                 delete_chat_from_db(chat_id);
3412                 char* msg_table = get_table_name_from_number(chat_id);
3413                 drop_table(msg_table);
3414                 free(msg_table);
3415         } else {
3416
3417         }
3418         ecore_timer_add(3, on_async_chat_deletion_requested, sel_grp_chats);
3419 }
3420
3421 void delete_selected_group_chat(tg_engine_data_s *tg_data, Eina_List *sel_grp_chats)
3422 {
3423         if (sel_grp_chats && eina_list_count(sel_grp_chats) > 0) {
3424
3425                 tg_data->current_group_chat_index = 0;
3426                 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3427
3428                 tgl_peer_id_t chat_id;
3429                 chat_id.id = group_chat_id;
3430                 chat_id.type = TGL_PEER_CHAT;
3431
3432                 tgl_peer_id_t self_id = tg_data->id;
3433
3434                 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3435         }
3436 }
3437
3438 void on_group_chat_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3439 {
3440         int chat_id = (int)callback_extra;
3441         tg_engine_data_s *tg_data = TLS->callback_data;
3442         if (success) {
3443                 // update database
3444                 // delete from peer table
3445                 delete_chat_from_db(chat_id);
3446                 char* msg_table = get_table_name_from_number(chat_id);
3447                 drop_table(msg_table);
3448                 free(msg_table);
3449                 send_group_chat_deleted_response(tg_data, chat_id, EINA_TRUE);
3450         } else {
3451                 send_group_chat_deleted_response(tg_data, chat_id, EINA_FALSE);
3452         }
3453 }
3454
3455 void leave_group_chat(tg_engine_data_s *tg_data, int group_chat_id)
3456 {
3457         tgl_peer_id_t chat_id;
3458         chat_id.id = group_chat_id;
3459         chat_id.type = TGL_PEER_CHAT;
3460
3461         tgl_peer_id_t self_id = tg_data->id;
3462
3463         tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_group_chat_delete_reponse, (void*)(group_chat_id));
3464 }
3465
3466 #if 0
3467 void on_new_msg_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
3468 {
3469         tg_engine_data_s *tg_data;
3470
3471         struct tgl_message *msg = callback_extra;
3472
3473         char *msg_table;
3474
3475         if (!chat_info) {
3476                 return;
3477         }
3478         if (!chat_info->user_list) {
3479                 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
3480                 return;
3481         }
3482
3483         tg_data = TLS->callback_data;
3484
3485         msg_table = get_table_name_from_number(chat_info->id.id);
3486
3487         create_buddy_msg_table(msg_table);
3488
3489         insert_chat_info_to_db(chat_info, NULL);
3490         struct tgl_photo *pic = &(chat_info->photo);
3491         if(pic) {
3492                 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
3493         }
3494
3495         tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3496
3497         char *type_of_change = strdup("add_user");
3498         tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_group_chat_info_updated, type_of_change);
3499
3500         free(msg_table);
3501 }
3502 #endif
3503
3504 void forward_message_to_buddy(int to_id, int type_of_chat, int from_id, int message_id, int temp_message_id)
3505 {
3506         char *msg_table = get_table_name_from_number(from_id);
3507         struct tgl_message* msg = get_message_from_message_table(temp_message_id, msg_table);
3508
3509         if (msg) {
3510                 tgl_peer_id_t id_to_send;
3511                 id_to_send.id = type_of_chat;
3512                 tgl_do_forward_message(s_info.TLS, id_to_send, message_id, &on_message_sent_to_buddy, (void*)(msg));
3513         }
3514         free(msg_table);
3515 }
3516
3517 void send_typing_status_to_buddy(int buddy_id, int type_of_chat, int typing_status)
3518 {
3519         tgl_peer_id_t id_to_send;
3520         id_to_send.id = type_of_chat;
3521         tgl_do_send_typing(s_info.TLS, id_to_send, typing_status, NULL, NULL);
3522 }
3523
3524 void send_message_to_buddy(int buddy_id, int message_id, int msg_type, char *msg_data, int type_of_chat)
3525 {
3526         // get type of chat from buddy_id.
3527         char *msg_table = get_table_name_from_number(buddy_id);
3528         struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3529
3530         if (msg) {
3531                 if (type_of_chat == TGL_PEER_USER) {
3532                         msg->from_id.type = TGL_PEER_USER;
3533                         msg->to_id.type = TGL_PEER_USER;
3534                         tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3535                 } else if (type_of_chat == TGL_PEER_CHAT) {
3536                         msg->from_id.type = TGL_PEER_CHAT;
3537                         msg->to_id.type = TGL_PEER_CHAT;
3538 #if 0
3539                         Eina_Bool is_present_in_chat_db = is_user_present_chat_table(msg->to_id.id);
3540                         if (!is_present_in_chat_db) {
3541                                 //sandeep
3542                                 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_new_msg_requested_chat_info_received, msg);
3543                                 return;
3544                         }
3545 #endif
3546                         tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3547                 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3548
3549                 } else {
3550
3551                 }
3552         }
3553         free(msg_table);
3554 }
3555
3556 void send_media_to_buddy(int buddy_id, int message_id, int media_id, int msg_type, char *file_path, int type_of_chat)
3557 {
3558         char *msg_table = get_table_name_from_number(buddy_id);
3559         struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3560
3561         if (msg) {
3562                 if (type_of_chat == TGL_PEER_USER) {
3563
3564                         msg->from_id.type = TGL_PEER_USER;
3565                         msg->to_id.type = TGL_PEER_USER;
3566
3567                         if (msg->media.type == tgl_message_media_photo) {
3568                                 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3569                         } else if (msg->media.type == tgl_message_media_document) {
3570                                 char *extn = strrchr(file_path, '.');
3571                                 if (extn) {
3572                                         extn = replace(extn, '.', "");
3573                                 }
3574                                 char *mime_type = NULL;;
3575                                 if (extn) {
3576                                         mime_type_get_mime_type(extn, &mime_type);
3577                                 }
3578
3579                                 if (strstr(mime_type, "video") != NULL) {
3580
3581                                         char* thumb_path = get_video_thumb_path_from_db(media_id);
3582                                         tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3583                                         if (thumb_path) {
3584                                                 free(thumb_path);
3585                                                 thumb_path = NULL;
3586                                         }
3587                                 } else if (strstr(mime_type, "audio") != NULL) {
3588                                         tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3589                                 } else {
3590
3591                                 }
3592                         } else if (msg->media.type == tgl_message_media_geo) {
3593                                 char *latitude = NULL;
3594                                 char *longitude = NULL;
3595                                 get_geo_location_from_db(media_id, &latitude, &longitude);
3596                                 if (latitude && longitude) {
3597                                         tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3598                                 }
3599                         } else if (msg->media.type == tgl_message_media_contact) {
3600                                 char *first_name = NULL;
3601                                 char *last_name = NULL;
3602                                 char *phone_num = NULL;
3603                                 get_contact_details_from_db(media_id, &first_name, &last_name, &phone_num);
3604                                 if (first_name && last_name && phone_num) {
3605                                         tgl_do_send_contact(s_info.TLS, msg->to_id, first_name, strlen(first_name), last_name, strlen(last_name), phone_num, strlen(phone_num), &on_message_sent_to_buddy, (void*) (msg));
3606                                 }
3607                         }
3608
3609                 } else if (type_of_chat == TGL_PEER_CHAT) {
3610                         msg->from_id.type = TGL_PEER_CHAT;
3611                         msg->to_id.type = TGL_PEER_CHAT;
3612
3613                         if (msg->media.type == tgl_message_media_photo) {
3614                                 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3615                         } else if (msg->media.type == tgl_message_media_document) {
3616
3617
3618                                 char *extn = strrchr(file_path, '.');
3619                                 if (extn) {
3620                                         extn = replace(extn, '.', "");
3621                                 }
3622                                 char *mime_type = NULL;;
3623                                 if (extn) {
3624                                         mime_type_get_mime_type(extn, &mime_type);
3625                                 }
3626
3627                                 if (strstr(mime_type, "video") != NULL) {
3628
3629                                         char* thumb_path = get_video_thumb_path_from_db(media_id);
3630                                         tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3631                                         if (thumb_path) {
3632                                                 free(thumb_path);
3633                                                 thumb_path = NULL;
3634                                         }
3635                                 } else if (strstr(mime_type, "audio") != NULL) {
3636                                         tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3637                                 } else {
3638
3639                                 }
3640                         } else if (msg->media.type == tgl_message_media_geo) {
3641                                 char *latitude = NULL;
3642                                 char *longitude = NULL;
3643                                 get_geo_location_from_db(media_id, &latitude, &longitude);
3644                                 if (latitude && longitude) {
3645                                         tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3646                                 }
3647                         }
3648
3649
3650                 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3651
3652                 } else {
3653
3654                 }
3655
3656         }
3657         free(msg_table);
3658
3659 }
3660
3661 void check_type_sizes(void)
3662 {
3663         if (sizeof(int) != 4u) {
3664                 logprintf("sizeof(int) isn't equal 4.\n");
3665                 exit(1);
3666         }
3667         if (sizeof(char) != 1u) {
3668                 logprintf("sizeof(char) isn't equal 1.\n");
3669                 exit(1);
3670         }
3671 }
3672
3673 int str_empty(char *str)
3674 {
3675         return((str == NULL) ||(strlen(str) < 1));
3676 }
3677
3678 void parse_config(void)
3679 {
3680         if (!s_info.disable_output) {
3681                 //printf("libconfig not enabled\n");
3682         }
3683
3684         char *rsa_path = ui_utils_get_resource(DEFAULT_RSA_FILE_NAME);
3685         tasprintf(&s_info.rsa_file_name, "%s", rsa_path);
3686         tasprintf(&s_info.config_full_path, "%s%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY);
3687         struct stat st = { 0 };
3688         if (stat(s_info.config_full_path, &st) == -1) {
3689                 mkdir(s_info.config_full_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3690         }
3691
3692         if (remove(s_info.rsa_file_name) == 0) {
3693                 //printf("File successfully deleted\n");
3694         }
3695
3696         tasprintf(&s_info.downloads_directory, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
3697
3698         if (s_info.binlog_enabled) {
3699                 tasprintf(&s_info.binlog_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, BINLOG_FILE);
3700                 tgl_set_binlog_mode(s_info.TLS, 1);
3701                 tgl_set_binlog_path(s_info.TLS, s_info.binlog_file_name);
3702         } else {
3703                 tgl_set_binlog_mode(s_info.TLS, 0);
3704                 //tgl_set_auth_file_path(auth_file_name;
3705                 tasprintf(&s_info.auth_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, AUTH_KEY_FILE);
3706                 tasprintf(&s_info.state_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, STATE_FILE);
3707                 tasprintf(&s_info.secret_chat_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, SECRET_CHAT_FILE);
3708         }
3709         tgl_set_download_directory(s_info.TLS, s_info.downloads_directory);
3710         if (!mkdir(s_info.downloads_directory, CONFIG_DIRECTORY_MODE)) {
3711                 if (!s_info.disable_output) {
3712                         //printf("[%s] created\n", downloads_directory);
3713                 }
3714         }
3715 }
3716
3717 void running_for_first_time(void)
3718 {
3719         check_type_sizes();
3720         if (!str_empty(s_info.config_filename)) {
3721                 return; // Do not create custom config file
3722         }
3723
3724         if (str_empty(s_info.config_directory)) {
3725                 s_info.config_directory = strdup(DEFAULT_TELEGRAM_PATH); // specific path for tizen application.
3726         }
3727
3728         struct stat st = {0};
3729         if (stat(s_info.config_directory, &st) == -1) {
3730                 mkdir(s_info.config_directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3731         }
3732
3733         tasprintf(&s_info.config_filename, "%s%s", s_info.config_directory, CONFIG_FILE);
3734
3735         int config_file_fd;
3736         // see if config file is there
3737         if (access(s_info.config_filename, R_OK) != 0) {
3738                 // config file missing, so touch it
3739                 config_file_fd = open(s_info.config_filename, O_CREAT | O_RDWR, 0600);
3740                 if (config_file_fd == -1)  {
3741                         perror("open[config_file]");
3742                         //printf("I: config_file=[%s]\n", config_filename);
3743                         exit(EXIT_FAILURE);
3744                 }
3745                 if (write(config_file_fd, DEFAULT_CONFIG_CONTENTS, strlen(DEFAULT_CONFIG_CONTENTS)) <= 0) {
3746                         perror("write[config_file]");
3747                         exit(EXIT_FAILURE);
3748                 }
3749                 close(config_file_fd);
3750         }
3751 }
3752
3753 void init_tl_engine(void *cbdata)
3754 {
3755         s_info.TLS = tgl_state_alloc();
3756         if (!s_info.TLS) {
3757                 /**
3758                  * @todo
3759                  * Unable to allocate the TGL State info.
3760                  */
3761                 return;
3762         }
3763
3764         running_for_first_time();
3765
3766         parse_config();
3767
3768         tgl_set_rsa_key(s_info.TLS, s_info.rsa_file_name);
3769         tgl_set_callback(s_info.TLS, &upd_cb, cbdata);
3770         tgl_set_net_methods(s_info.TLS, &tgl_conn_methods);
3771         tgl_set_timer_methods(s_info.TLS, &tgl_libevent_timers);
3772         assert(s_info.TLS->timer_methods);
3773         tgl_set_download_directory(s_info.TLS, tgl_engine_get_downloads_directory());
3774         tgl_register_app_id(s_info.TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH);
3775         tgl_set_app_version(s_info.TLS, "Telegram-cli " TELEGRAM_CLI_VERSION);
3776         if (s_info.ipv6_enabled) {
3777                 tgl_enable_ipv6(s_info.TLS);
3778         }
3779         tgl_init(s_info.TLS);
3780
3781         if (s_info.binlog_enabled) {
3782                 double t = tglt_get_double_time();
3783                 if (s_info.verbosity >= E_DEBUG) {
3784                         logprintf("replay log start\n");
3785                 }
3786                 tgl_replay_log(s_info.TLS);
3787                 if (s_info.verbosity >= E_DEBUG) {
3788                         logprintf("replay log end in %lf seconds\n", tglt_get_double_time() - t);
3789                 }
3790                 tgl_reopen_binlog_for_writing(s_info.TLS);
3791         } else {
3792                 read_auth_file();
3793                 read_state_file();
3794                 read_secret_chat_file();
3795         }
3796 }
3797
3798 void tgl_engine_destroy_TLS(void)
3799 {
3800         if (!s_info.TLS) {
3801                 return;
3802         }
3803
3804         tgl_state_free(tgl_engine_get_TLS());
3805         s_info.TLS = NULL;
3806 }
3807
3808 struct tgl_state *tgl_engine_get_TLS(void)
3809 {
3810         return s_info.TLS;
3811 }