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