Update change log and spec for wrt-plugins-tizen_0.2.73
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Messaging / Email.cpp
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. 
15 */
16
17
18 /**
19  *
20  *
21  * @file       Email.cpp
22  * @author     Pawel Misiak (p.misiak@samsung.com)
23  * @version    0.1
24  * @brief
25  */
26 #include <cstdio>
27 #include <cstddef>
28 #include <cstdlib>
29 #include <ctime>
30 #include <email-types.h>
31 #include <email-api.h>
32 #include <dpl/log/log.h>
33 #include <dpl/assert.h>
34 #include <dpl/scoped_fclose.h>
35 #include <dpl/scoped_ptr.h>
36 #include <Commons/Exception.h>
37 #include <Commons/StringUtils.h>
38 #include <API/Messaging/MessageFactory.h>
39 #include "Messaging.h"
40 #include "Email.h"
41 #include "EmailService.h"
42 #include "EmailUtils.h"
43 #include "EmailConverter.h"
44 #include "MailSender.h"
45 #include "MailSync.h"
46 #include "MessagingService.h"
47 #include "MessagingServiceManager.h"
48 #include "Attachment.h"
49
50 #define LOG_ENTER LogDebug("---> ENTER");
51 #define LOG_EXIT LogDebug("---> EXIT");
52
53 using namespace std;
54 using namespace TizenApis::Api::Messaging;
55 using namespace WrtDeviceApis::Commons;
56
57 namespace TizenApis {
58 namespace Platform {
59 namespace Messaging {
60
61 namespace {
62 const char* COMMAND_NAME = "/bin/cp";
63 const char* COMMAND_SWITCH_RECURSIVE = "-r";
64 //const char* COMMAND_SWITCH_FORCE = "-f";
65 }
66
67 Email::Email(const string& id) :
68         IMessage(EMAIL, id) {
69         LOG_ENTER
70
71         try {
72                 if (getIdRef().empty()) {
73                         //exception
74                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, " message id is invalid");
75                 }
76                                 
77                 reload();
78         } catch (const WrtDeviceApis::Commons::PlatformException& ex) {
79                 LogError("Exception: " << ex.DumpToString());
80         }
81
82         LOG_EXIT
83 }
84
85 Email::Email(const std::string& id, int accountId) :
86         IMessage(EMAIL, id) 
87 {
88         LOG_ENTER
89
90         try {
91                 if (getIdRef().empty()) {
92                         //exception
93                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, " message id is invalid");
94                 }
95                 
96                 LogDebug("Account ID = " << accountId);
97                 m_accountId = accountId;
98                 reload();
99                 
100         } catch (const WrtDeviceApis::Commons::PlatformException& ex) {
101                 LogError("Exception: " << ex.DumpToString());
102         }
103
104
105         LOG_EXIT
106 }
107
108 Email::Email(Api::Messaging::EmailAccountInfo& account) : IMessage(EMAIL)
109 {
110     LOG_ENTER
111
112     try {
113          if (getIdRef().empty()) {
114                 create(account);
115          }
116         
117         reload();
118     }
119     catch (const WrtDeviceApis::Commons::PlatformException& ex) {
120         LogError("Exception: " << ex.DumpToString());
121     }
122
123     LOG_EXIT
124 }
125
126 Email::Email(const Api::Messaging::FolderType folder) : IMessage(EMAIL)
127 {
128     LOG_ENTER
129
130     try {
131          if (folder == Api::Messaging::TEMP_FOLDER) {
132                 create();
133          }
134            else {
135               ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Folder Type is miss-matched");
136            }
137     }
138     catch (const WrtDeviceApis::Commons::PlatformException& ex) {
139         LogError("Exception: " << ex.DumpToString());
140     }
141
142     LOG_EXIT
143 }
144
145 Email::~Email()
146 {
147     LogDebug("ENTER");
148 }
149
150 int Email::send()
151 {
152     LOG_ENTER
153
154     update();
155
156     int handle = MailSender::getInstance().send(
157         Api::Messaging::MessageFactory::convertToEmail(SharedFromThis())
158         );
159
160     return handle;
161     LOG_EXIT
162 }
163
164 void Email::sendCancel(int handle)
165 {
166     LOG_ENTER
167
168     MailSender::getInstance().cancel(handle);
169
170     LOG_EXIT
171 }
172
173 int Email::downloadBody()
174 {
175         LOG_ENTER
176         return MailSync::getInstance().downloadBody( Api::Messaging::MessageFactory::convertToEmail(SharedFromThis()) );
177         LOG_EXIT
178 }
179
180 void Email::downloadBodyCancel( int handle)
181 {       
182         return MailSync::getInstance().cancelDownloadBody(handle);
183 }
184
185 int Email::downloadAttachment( const Api::Messaging::IAttachmentPtr& attachment)
186 {
187         LOG_ENTER
188         return MailSync::getInstance().downloadAttachment( Api::Messaging::MessageFactory::convertToEmail(SharedFromThis()), attachment );
189         LOG_EXIT
190 }
191
192 void Email::downloadAttachmentCancel( int handle)
193 {       
194         LOG_ENTER
195         return MailSync::getInstance().cancelDownloadAttachment(handle);
196         LOG_EXIT
197 }
198
199 void Email::update(bool draftsOnly)
200 {
201     LOG_ENTER
202
203     DPL::Mutex::ScopedLock mx(&m_updateMutex);
204
205     if (!m_mail) {
206         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
207     }
208
209     updateSubject();
210     updateBody();
211     updateRecipients();
212     updateAttachments();
213     updateReadStatus();
214
215     email_attachment_data_t* attachment=NULL;
216     int attachmentCount = 0;
217     int error = email_get_attachment_data_list( m_mail->mail_id, &attachment, &attachmentCount);
218     if (EMAIL_ERROR_NONE != error) {
219           LogWarning("Nothing to update or error. [" << error << "]");
220     }
221
222     error = email_update_mail( m_mail.Get(), attachment, attachmentCount, NULL, 0);
223     if (EMAIL_ERROR_NONE != error) {
224           LogWarning("Nothing to update or error. [" << error << "]");
225     }
226
227     if (attachment)
228     {
229             error = email_free_attachment_data(&attachment, attachmentCount);
230             if (EMAIL_ERROR_NONE != error) {
231                   LogWarning("Nothing to update or error. [" << error << "]");
232             }
233     }
234 #if 0   
235     LogDebug("getCurrentFolder() = " << getCurrentFolder() );
236     if (!draftsOnly || (getCurrentFolder() == Api::Messaging::DRAFTBOX)) {
237                 
238         updateBody();
239         updateSubject();
240         updateRecipients();
241         updateAttachments();
242         updatePriority();
243                 
244     } else {
245         LogWarning("Updating only read status. Folder: " << getCurrentFolder());
246     }
247     updateReadStatus();
248
249     //get attachment
250     email_attachment_data_t* attachment=NULL;
251     int attachmentCount = 0;
252     int error = email_get_attachment_data_list( m_mail->mail_id, &attachment, &attachmentCount);
253     if (EMAIL_ERROR_NONE != error) {
254           LogWarning("Nothing to update or error. [" << error << "]");
255     }
256
257     error = email_update_mail( m_mail.Get(), attachment, attachmentCount, NULL, 0);
258     if (EMAIL_ERROR_NONE != error) {
259           LogWarning("Nothing to update or error. [" << error << "]");
260     }
261 #endif
262
263     LOG_EXIT
264 }
265
266 int Email::getAccountID()
267 {
268         LOG_ENTER
269
270         if ( m_mail )
271                 return m_mail->account_id;
272         else
273                 return -1;
274         
275         LOG_EXIT
276 }
277
278 int Email::getUID()
279 {
280         LOG_ENTER
281         
282         if (m_mail)
283                 return m_mail->mail_id;
284         else
285                 return -1;
286
287         LOG_EXIT
288 }
289
290 int Email::isBodyDownloaded()
291 {
292
293         if (m_mail)
294                 if ( m_mail->body_download_status == 1 )        // 1 is fully downloaded body.
295                         return true;
296                 else
297                         return false;
298         else
299                 return false;
300
301 }
302
303 bool Email::hasAttachment()
304 {       
305         std::size_t attachmentSize = getAttachmentsCount();
306         if ( attachmentSize > 0)
307                         return true;
308                 else
309                         return false;
310 }
311
312 void Email::readAllData()
313 {
314     reload();
315 }
316
317 void Email::moveToFolder(const FolderType newFolder)
318 {
319 /*
320
321     LOG_ENTER
322     moveToFolder(EmailConverter::toMailboxType(newFolder));
323     LOG_EXIT
324 */
325 }
326
327 void Email::moveToFolder(const string& newFolder)
328 {
329 /*
330         Assert(m_mail && "mail is NULL.");
331         
332         update();
333
334         int accountId = m_mail->account_id;
335         int mailId = getIntId();
336
337         emf_mailbox_t* mailbox = EmailService::alloc<emf_mailbox_t>();
338         mailbox->account_id = accountId;
339         mailbox->name = (NULL != newFolder.c_str() ? strdup(newFolder.c_str()) : NULL);
340
341         int error = email_move_mail_to_mailbox(&mailId, 1, mailbox);
342         if (EMF_ERROR_NONE != error) {
343         ThrowMsg(
344             WrtDeviceApis::Commons::PlatformException,
345             "Couldn't move mail to folder: " << newFolder << ". [" <<
346             error << "]");
347         }
348         
349         error = email_free_mailbox(&mailbox, 1);        //free
350         if (EMF_ERROR_NONE != error) {
351             LogError("Failed to destroy mailbox: " << error);
352         }
353 */
354 }
355
356 void Email::copyToFolder(const FolderType newFolder)
357 {
358     LOG_ENTER
359
360     copyToFolder(EmailConverter::toMailboxName(newFolder));
361
362     LOG_EXIT
363 }
364
365 void Email::copyToFolder(const string& newFolder)
366 {
367         LOG_ENTER
368 /*              
369         Assert(m_mail && "mail is NULL.");
370
371         update();
372
373         int accountId = m_mail->account_id;
374         ScopedMail mail(EmailService::cloneMail(m_mail.Get())); //clone
375         mail->mailbox_name = (NULL != newFolder.c_str() ? strdup(newFolder.c_str()) : NULL);
376         mail->account_id = accountId;
377         
378         //Attachment
379         email_attachment_data_t* attachment = NULL;
380         int attachmentCount = 0;
381         int error = email_get_attachment_data_list( m_mail->mail_id, &attachment, &attachmentCount);    //get Attachment list
382         if (EMAIL_ERROR_NONE != error) {
383                 ThrowMsg( WrtDeviceApis::Commons::PlatformException,
384                         "Couldn't get attachment list: " << newFolder << ". [" << error << "]");
385         }
386         
387         int mailId = EmailService::addMail( mail.Get(), attachment );
388         if (0 == mailId) {
389             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Cloned mail didn't get new id.");
390         }
391 */      
392     LOG_EXIT
393 }
394
395 void Email::remove()
396 {
397     EmailService::deleteMail(m_accountId, getIntId());
398 }
399
400 #if 0
401 void Email::create()
402 {
403     LOG_ENTER
404
405     EmailAccountInfo account = IMessaging::getInstance().getCurrentEmailAccount();
406     m_accountId = account.getIntId();
407     ScopedMail mail(EmailService::createMail(account));
408     ScopedMailbox mailbox(
409         EmailService::getMailboxByType(account.getIntId(),
410                                        EMAIL_MAILBOX_TYPE_DRAFT)
411         );
412     setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
413     setFolderType(Api::Messaging::DRAFTBOX);
414     setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
415
416     LOG_EXIT
417 }
418 #endif
419
420 void Email::create()
421 {
422     LOG_ENTER
423     setFolderType(Api::Messaging::TEMP_FOLDER);
424     setMessageStatus(Api::Messaging::MESSAGE_STATUS_CREATED);
425     LOG_EXIT
426 }
427
428 void Email::create( Api::Messaging::EmailAccountInfo& account )
429 {
430         LOG_ENTER
431
432         m_accountId = account.getIntId();
433         //MailSender::getInstance();
434         
435       LogDebug("account ID : " << m_accountId);
436         ScopedMail mail(EmailService::createMailData(account));
437         
438         setEmailAccount(account);       //save account
439
440         mail->mailbox_type = EMAIL_MAILBOX_TYPE_DRAFT;
441         
442         setId(convertId(EmailService::addMail(mail.Get(), NULL)));
443         setFolderType(Api::Messaging::DRAFTBOX);
444         setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
445         
446     LOG_EXIT
447 }
448
449 void Email::reload()
450 {
451     LOG_ENTER
452
453     LogDebug("mail ID :" << getIntId());
454     m_mail.Reset(EmailService::readMail(getIntId()));           //reset Mail Data
455
456     readHeader();
457     readBody();
458     readInfo();
459
460     //if (m_mail->head) { readHeader(); }
461     //if (m_mail->body) { readBody(); }
462     //if (m_mail->info) { readInfo(); }
463
464     //m_mailbox.Reset(EmailService::getMailboxByMailId(m_accountId, getIntId()) );
465     //setFolderType(EmailConverter::toFolderType(m_mailbox->mailbox_type));
466     
467     setFolderType(EmailConverter::toFolderType(m_mail->mailbox_type));
468
469     LOG_EXIT
470 }
471
472 void Email::readHeader()
473 {
474     LOG_ENTER
475
476     Assert(m_mail && "Header is NULL.");
477
478     if (m_mail->subject) {
479         setSubject(m_mail->subject);
480     }
481
482     if (m_mail->full_address_to) {
483         appendToRecipients(EmailUtils::stripAddressLine(m_mail->full_address_to));
484     }
485
486     if (m_mail->full_address_cc) {
487         appendCcRecipients(EmailUtils::stripAddressLine(m_mail->full_address_cc));
488     }
489
490     if (m_mail->full_address_bcc) {
491         appendBccRecipients(EmailUtils::stripAddressLine(m_mail->full_address_bcc));
492     }
493
494 #if 1
495     struct tm *t;
496     t = localtime(&m_mail->date_time);
497     struct tm timeinfo;
498     memcpy(t, &timeinfo, sizeof(struct tm));
499     setDateTime(timeinfo); 
500
501 #else
502
503         if (m_mail->datetime[0] != '\0')
504         {
505                 char buf[MAX_DATETIME_STRING_LENGTH];
506                 char *targetBuf = m_mail->datetime;
507                 struct tm timeinfo;
508
509                 memset(buf, 0x00, sizeof(buf));
510                 targetBuf += snprintf(buf, sizeof(buf), "%.4s", targetBuf);
511                 timeinfo.tm_year = atoi(buf) - 1900;
512
513                 memset(buf, 0x00, sizeof(buf));
514                 targetBuf += snprintf(buf, sizeof(buf), "%.2s", targetBuf);
515                 timeinfo.tm_mon =  atoi(buf) - 1;
516
517                 memset(buf, 0x00, sizeof(buf));
518                 targetBuf += snprintf(buf, sizeof(buf), "%.2s", targetBuf);
519                 timeinfo.tm_mday =      atoi(buf);
520
521                 memset(buf, 0x00, sizeof(buf));
522                 targetBuf += snprintf(buf, sizeof(buf), "%.2s", targetBuf);
523                 timeinfo.tm_hour = atoi(buf);
524
525                 memset(buf, 0x00, sizeof(buf));
526                 targetBuf += snprintf(buf, sizeof(buf), "%.2s", targetBuf);
527                 timeinfo.tm_min = atoi(buf);
528
529                 memset(buf, 0x00, sizeof(buf));
530                 targetBuf += snprintf(buf, sizeof(buf), "%.2s", targetBuf);
531                 timeinfo.tm_sec = atoi(buf);
532                 
533                 setDateTime(timeinfo);
534         }
535
536 #endif
537         
538 #if 0
539     time_t rawtime;
540     time(&rawtime);
541     struct tm tmpTime = *(localtime(&rawtime));
542
543     tmpTime.tm_year = m_mail->head->datetime.year;
544     tmpTime.tm_mon = m_mail->head->datetime.month;
545     tmpTime.tm_mday = m_mail->head->datetime.day;
546     tmpTime.tm_hour = m_mail->head->datetime.hour;
547     tmpTime.tm_min = m_mail->head->datetime.minute;
548     tmpTime.tm_sec = m_mail->head->datetime.second;
549     mktime(&tmpTime);
550     setDateTime(tmpTime);
551 #endif
552
553     if (m_mail->full_address_from) {
554         Recipients from;
555         from.setRecipients(m_mail->full_address_from);
556         setSourceAddress(from);
557         setSourceAddressValidity(true); //not needed to update in platform
558     }
559
560     LOG_EXIT
561 }
562
563 void Email::readBody() {
564         LOG_ENTER
565
566         Assert(m_mail && "Body is NULL.");
567
568         if (m_mail->file_path_plain) {
569                 DPL::ScopedFClose file(::fopen(m_mail->file_path_plain, "r"));
570                 if (!file) {
571                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
572                                         "Cannot read body file: " << m_mail->file_path_plain);
573                 }
574                 fseek(file.Get(), 0, SEEK_END);
575                 long int size = ftell(file.Get());
576                 fseek(file.Get(), 0, SEEK_SET);
577                 DPL::ScopedPtr<char> data(new char[size + 1]);
578                 memset(data.Get(), 0, size + 1);
579                 fread(data.Get(), 1, size, file.Get());
580                 setBody(data.Get());
581         }
582
583         //html body.
584         if (m_mail->file_path_html) {
585                 DPL::ScopedFClose file(::fopen(m_mail->file_path_html, "r")); //auto close, scopedFClose
586                 if (!file) {
587                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
588                                         "Cannot read html body file: " << m_mail->file_path_html);
589                 }
590
591                 fseek(file.Get(), 0, SEEK_END);
592                 long int size = ftell(file.Get());
593                 fseek(file.Get(), 0, SEEK_SET);
594                 DPL::ScopedPtr<char> data(new char[size + 1]);
595                 memset(data.Get(), 0, size + 1);
596                 fread(data.Get(), 1, size, file.Get());
597                 setHtmlBody(data.Get()); //setHtmlBody declarate in Email Calss.
598         }
599
600         //Attachment
601         //email_attachment_info_t* attachment = NULL;
602         email_attachment_data_t* attachment = NULL;
603         int attachmentCount = 0;
604         
605         int error = email_get_attachment_data_list( m_mail->mail_id, &attachment, &attachmentCount);    //get Attachment list
606         if (EMAIL_ERROR_NONE != error) {
607                 ThrowMsg( WrtDeviceApis::Commons::PlatformException, "Couldn't get attachment list: ");
608         }
609         
610         if ( attachment && attachmentCount > 0)
611         {
612                 LogDebug("reading attachments , attahcment count = " << attachmentCount);
613                 int i = 0;
614
615                 for ( i = 0; i < attachmentCount; i++)
616                 {
617                         Try {
618                                 LogDebug("attachment ID :" << attachment[i].attachment_id << " name :" << attachment[i].attachment_name << " download :" << attachment[i].save_status << "savefile :" << attachment[i].attachment_path);
619                                                         
620                                 IAttachmentPtr tmpAtt(new Attachment());
621                                 if (attachment[i].attachment_path)
622                                         tmpAtt->init(attachment[i].attachment_path, false);
623                         
624                                 if (tmpAtt)
625                                 {
626                                         tmpAtt->rename(std::string(attachment[i].attachment_name));
627                                         tmpAtt->setAttachmentID(attachment[i].attachment_id);
628                                         tmpAtt->setDownloaded(attachment[i].save_status);
629                                         //tmpAtt->setMimeType(std::string(attachment[i].attachment_mime_type));
630                                         tmpAtt->setNth(i+1);
631                         
632                                         appendAttachment(tmpAtt);
633                                 }
634                                         LogDebug(" append Attachment complete");
635
636                         
637                         }
638                         catch ( const WrtDeviceApis::Commons::Exception& ex )
639                         {
640                                 LogError("Error while trying to append attachment " << attachment[i].attachment_path << ": " << ex.DumpToString());
641                         }
642                         
643                 }
644
645              if (attachment)
646              {
647                         error = email_free_attachment_data(&attachment, attachmentCount);
648                         if (EMAIL_ERROR_NONE != error) {
649                                 ThrowMsg( WrtDeviceApis::Commons::PlatformException, " attachment_data free error! ");
650                         }
651              }
652         }
653
654         LOG_EXIT
655 }
656
657 void Email::readInfo()
658 {
659     LOG_ENTER
660
661     Assert(m_mail && "Info is NULL.");
662
663     setReadStatus(m_mail->flags_seen_field == 1);
664
665     m_accountId = m_mail->account_id;
666
667     setPriority( EmailConverter::toMessagePriority( m_mail->priority ) );
668     setSize(m_mail->mail_size);
669
670     LOG_EXIT
671 }
672
673 void Email::updateBody()
674 {
675     LOG_ENTER
676
677     if (isBodyValid()) { return; }
678
679     if (!m_mail) {
680         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
681     }
682     if (!m_mail->file_path_plain) {
683         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Plain Body is NULL.");
684     }
685 // fix email empty plain text
686 /*
687     if (!m_mail->file_path_html) {
688         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Html Body file is NULL.");
689     }
690 */
691     if ((!m_mail->file_path_html) && (strlen(getHtmlBody().c_str()) > 0) ) {
692         std::string htmlFile = tmpnam(NULL);
693         FILE* f = fopen(htmlFile.c_str(), "w");
694         fclose(f);
695         m_mail->file_path_html = strdup(htmlFile.c_str());
696                 
697         if(!m_mail->file_path_html)
698         {
699             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Html Body file is NULL.");
700         }
701     }
702    
703     //update plain body.
704     FILE* f = fopen(m_mail->file_path_plain, "w");
705     if (NULL != f) {
706         fwrite(getBodyRef().c_str(), strlen(getBodyRef().c_str()), 1, f);
707         fclose(f);
708     }
709     else
710     {
711           LogDebug("Plain Body file is NULL.");
712           ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Plain Body File Open Error");
713     }
714
715     //update html body (if exist)
716     if (m_mail->file_path_html)
717     {
718         //update html body
719         f = fopen(m_mail->file_path_html, "w");
720         if (NULL != f) {
721             //fprintf(f, getHtmlBody().c_str());
722             fwrite(getHtmlBody().c_str(), strlen(getHtmlBody().c_str()), 1, f);
723             fclose(f);
724         }
725     }
726     // fix email empty plain text       
727 /*
728     else
729     {
730                 LogDebug("Html Body file is NULL.");
731                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "HTML Body File Open Error");
732     }
733 */
734     m_mail->body_download_status = true;
735         
736     setBodyValidity(true);
737
738     LOG_EXIT
739 }
740
741 void Email::updateSubject()
742 {
743     LOG_ENTER
744
745     if (isSubjectValid()) { return; }
746
747     LogDebug("update subject, msgId=" << getIdRef());
748
749     if (!m_mail) {
750         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
751     }
752     
753     m_mail->subject = String::strdup(getSubjectRef());
754     setSubjectValidity(true);
755
756     LOG_EXIT
757 }
758
759 void Email::updateReadStatus()
760 {
761     LOG_ENTER
762
763     if (isReadStatusValid()) { return; }
764
765     LogDebug("update read, msgId=" << getIdRef());
766
767     if (!m_mail) {
768         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
769     }
770
771     m_mail->flags_seen_field = isRead();
772     setReadStatusValidity(true);
773
774     LOG_EXIT
775 }
776
777 void Email::updateIsRead()
778 {
779     LOG_ENTER
780     if (isReadChangeStatusValid()) {
781         // do not update if not changed
782         return;
783     }
784
785     EmailService::updateSeenFlag(getAccountID(), getIntId(), isReadChangeStatus());
786     setisReadChangeStatusValidity(true);
787     LOG_EXIT
788 }
789
790 void Email::updateMessage()
791 {
792         LOG_ENTER
793         email_meeting_request_t *meeting_req = NULL;
794
795         DPL::Mutex::ScopedLock mx(&m_updateMutex);
796
797         if (!m_mail) {
798                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
799         }
800
801         LogDebug("getCurrentFolder() = " << getCurrentFolder() );
802
803         if(getCurrentFolder() == Api::Messaging::DRAFTBOX)
804         {
805                 updateBody();
806                 updateSubject();
807                 updateRecipients();
808                 updateFrom();
809                 updateAttachments();
810                 updatePriority();
811         }
812         updateReadStatus();
813
814         //get attachment
815         email_attachment_data_t* attachment=NULL;
816         int attachmentCount = 0;
817         int error = email_get_attachment_data_list( m_mail->mail_id, &attachment, &attachmentCount);
818         if (EMAIL_ERROR_NONE != error) {
819                 LogWarning("email_get_attachment_data_list [" << error << "]");
820         }
821
822         error = email_get_meeting_request(m_mail->mail_id, &meeting_req);
823         if (EMAIL_ERROR_NONE != error) {
824                 LogWarning("email_get_meeting_request() failed [%d]\n" << error);
825         }
826
827         error = email_update_mail( m_mail.Get(), attachment, attachmentCount, meeting_req, 0);
828         if (EMAIL_ERROR_NONE != error) {
829                 LogWarning("Nothing to update or error. [" << error << "]");
830         }
831
832         if(meeting_req) {
833                 email_free_meeting_request(&meeting_req, 1);
834         }
835
836         LOG_EXIT
837 }
838
839 void Email::createSendMessage()
840 {
841         LOG_ENTER
842
843     MailSender::getInstance(); //start email service
844
845         if ( getUID() > 0 && m_accountId > 0)
846         {       
847                 update();
848         }
849         else
850         {       
851         DPL::Mutex::ScopedLock mx(&m_updateMutex);
852                 
853                 Api::Messaging::EmailAccountInfo account = getEmailAccount();
854                 m_accountId = account.getIntId();       //set account ID
855                 LogDebug("account ID : " << m_accountId);
856                 m_mail.Reset(EmailService::createMailData(account));
857                 
858                 updateSubject();
859                 updateBody();
860                 updateRecipients();
861                 updatePriority();
862                 updateReadStatus();
863                 
864                 email_mailbox_t* mailbox;
865                 int error = email_get_mailbox_by_mailbox_type(m_accountId, EMAIL_MAILBOX_TYPE_OUTBOX, &mailbox );
866                 if (EMAIL_ERROR_NONE != error) {
867                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
868                         "Couldn't add message to mailbox. [" << error << "]");
869                 }
870                 if ( mailbox->mailbox_id )
871                         m_mail->mailbox_id = mailbox->mailbox_id;
872                 LogDebug("mail MailBox id :" << m_mail->mailbox_id);
873
874                 error = email_add_mail(m_mail.Get(), NULL, 0, NULL, 0);
875                 if (EMAIL_ERROR_NONE != error) {
876                        ThrowMsg(WrtDeviceApis::Commons::PlatformException,
877                                 "Couldn't add message to mailbox. [" << error << "]");
878                 }
879                 
880                 LogDebug("message id =" << m_mail->mail_id);
881                 
882                 setId(convertId(m_mail->mail_id));
883                 setFolderType(OUTBOX);
884                 setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENDING);
885
886                 updateAttachments();    //update Attachment.
887                 
888                 error = email_free_mailbox(&mailbox, 1);
889                 if (EMAIL_ERROR_NONE != error) {
890                         LogError("Failed to destroy mailbox: " << error);
891                 }
892
893                 LogDebug("m_mail->from" << m_mail->full_address_from);
894
895                 email_mail_data_t* result = NULL;
896
897                 error = email_get_mail_data(m_mail->mail_id, &result);
898                 if (EMAIL_ERROR_NONE != error) {
899                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
900                              "Couldn't find message " << m_mail->mail_id << ". [" << error << "]");
901                 }
902
903                 if (m_mail->file_path_plain)
904                         free(m_mail->file_path_plain);
905                 m_mail->file_path_plain = strdup(result->file_path_plain);
906                 
907                 if ( m_mail->file_path_html)
908                 {
909                         free(m_mail->file_path_html);
910                 }
911
912                 if(result->file_path_html)
913                 {
914                         m_mail->file_path_html = strdup(result->file_path_html);
915                 }
916                 
917                 error = email_free_mail_data(&result, 1);
918                 if (EMAIL_ERROR_NONE != error) {
919                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
920                              "Couldn't find message " << m_mail->mail_id << ". [" << error << "]");
921                 }               
922
923     }
924         LOG_EXIT
925 }
926
927
928 void Email::addMessageToDraft()
929 {
930     LOG_ENTER
931
932     MailSender::getInstance(); //start email service
933         
934     if ( getUID() > 0 && m_accountId > 0)
935     {   
936                 update();
937     }
938     else
939     {   
940                 DPL::Mutex::ScopedLock mx(&m_updateMutex);
941                 
942                 Api::Messaging::EmailAccountInfo account = getEmailAccount();
943                 m_accountId = account.getIntId();       //set account ID
944                 LogDebug("account ID : " << m_accountId);
945                 m_mail.Reset(EmailService::createMailData(account));
946                 
947                 updateSubject();
948                 updateBody();
949                 updateRecipients();
950                 updatePriority();
951                 updateReadStatus();
952                 
953                 email_mailbox_t* mailbox;
954                 int error = email_get_mailbox_by_mailbox_type(m_accountId, EMAIL_MAILBOX_TYPE_DRAFT, &mailbox );
955                 if (EMAIL_ERROR_NONE != error) {
956                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
957                         "Couldn't add message to mailbox. [" << error << "]");
958                 }
959                 if ( mailbox->mailbox_id )
960                         m_mail->mailbox_id = mailbox->mailbox_id;
961                 LogDebug("mail MailBox id :" << m_mail->mailbox_id);
962
963                 error = email_add_mail(m_mail.Get(), NULL, 0, NULL, 0);
964                 if (EMAIL_ERROR_NONE != error) {
965                        ThrowMsg(WrtDeviceApis::Commons::PlatformException,
966                                 "Couldn't add message to mailbox. [" << error << "]");
967                 }
968                 
969                 LogDebug("message id =" << m_mail->mail_id);
970                 
971                 setId(convertId(m_mail->mail_id));
972                 setFolderType(DRAFTBOX);
973                 setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
974
975                 updateAttachments();    //update Attachment.
976                 
977                 error = email_free_mailbox(&mailbox, 1);
978                 if (EMAIL_ERROR_NONE != error) {
979                         LogError("Failed to destroy mailbox: " << error);
980                 }
981
982                 LogDebug("m_mail->from" << m_mail->full_address_from);
983
984                 email_mail_data_t* result = NULL;
985
986                 error = email_get_mail_data(m_mail->mail_id, &result);
987                 if (EMAIL_ERROR_NONE != error) {
988                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
989                              "Couldn't find message " << m_mail->mail_id << ". [" << error << "]");
990                 }
991
992                 if (m_mail->file_path_plain)
993                         free(m_mail->file_path_plain);
994                 m_mail->file_path_plain = strdup(result->file_path_plain);
995                 
996                 if ( m_mail->file_path_html)
997                 {
998                         free(m_mail->file_path_html);
999                 }
1000
1001                 if(result->file_path_html)
1002                 {
1003                         m_mail->file_path_html = strdup(result->file_path_html);
1004                 }
1005                 
1006                 error = email_free_mail_data(&result, 1);
1007                 if (EMAIL_ERROR_NONE != error) {
1008                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1009                              "Couldn't find message " << m_mail->mail_id << ". [" << error << "]");
1010                 }               
1011
1012     }
1013
1014     LOG_EXIT
1015 }
1016
1017 void Email::updateRecipients()
1018 {
1019     LOG_ENTER
1020
1021     if (getToValidity() && getCcValidity() && getBccValidity()) { return; }
1022
1023     if (!m_mail) {
1024         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
1025     }
1026
1027     if (!getToValidity()) {
1028         std::string addressLine = EmailUtils::formatAddressLine(getToRecipients());
1029         if (m_mail->full_address_to) {
1030             free(m_mail->full_address_to);
1031         }
1032         m_mail->full_address_to = String::strdup(addressLine);
1033         setToValidity(true);
1034     }
1035
1036     if (!getCcValidity()) {
1037         std::string addressLine = EmailUtils::formatAddressLine(getCcRecipients());
1038         if (m_mail->full_address_cc) {
1039             free(m_mail->full_address_cc);
1040         }
1041         m_mail->full_address_cc = String::strdup(addressLine);
1042         setCcValidity(true);
1043     }
1044
1045     if (!getBccValidity()) {
1046         std::string addressLine = EmailUtils::formatAddressLine(
1047                 getBccRecipients());
1048         if (m_mail->full_address_bcc) {
1049             free(m_mail->full_address_bcc);
1050         }
1051         m_mail->full_address_cc = String::strdup(addressLine);
1052         setBccValidity(true);
1053     }
1054
1055     LOG_EXIT
1056 }
1057
1058 void Email::updateFrom()
1059 {
1060     LOG_ENTER
1061
1062     if (getFromValidity()) { return; }
1063
1064     if (!m_mail) {
1065         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
1066     }
1067
1068     m_mail->account_id = m_accountId;
1069
1070     if (m_mail->full_address_from) {
1071           free(m_mail->full_address_from);
1072     }
1073     m_mail->full_address_from = String::strdup(getFrom());
1074
1075     setFromValidity(true);
1076
1077     LOG_EXIT
1078 }
1079
1080 void Email::updateAttachments()
1081 {
1082     LOG_ENTER
1083
1084     if (isAttachmentsValid()) { return; }
1085
1086     if (!m_mail) {
1087         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
1088     }
1089
1090     email_attachment_data_t* attachment = NULL;
1091     int attachmentCount = 0;            
1092     email_mailbox_t* mailBox = NULL;
1093     int error = 0;
1094
1095     Try {
1096                  //clean attachment
1097                 LogDebug("update attachments, msgId=" << getIdRef());
1098                 error = email_get_attachment_data_list( m_mail->mail_id, &attachment, &attachmentCount);        //get Attachment list
1099                 if (EMAIL_ERROR_NONE != error) {
1100                         ThrowMsg( WrtDeviceApis::Commons::PlatformException, "Couldn't get attachment list: ");
1101                 }
1102 //              error = email_get_mailbox_by_name(m_mail->account_id, m_mail->mailbox_name, &mailBox);
1103 //              if (EMAIL_ERROR_NONE != error) {
1104 //                      ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1105 //                                               "Couldn't find message " << m_mail->mail_id << ". [" << error << "]");
1106 //              }
1107 //
1108                 error = email_get_mailbox_by_mailbox_id(m_mail->mailbox_id, &mailBox);
1109                 
1110                 if (EMAIL_ERROR_NONE != error) {
1111                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1112                         "Couldn't get mailbox. [" << error << "]");
1113                 }       
1114                  
1115                 if ( attachmentCount > 0 )
1116                 {
1117                         int i = 0;
1118                         std::stringstream stream;
1119                         for ( i = 0; i < attachmentCount; i++)
1120                         {
1121                                 LogDebug("file name:" << attachment[i].attachment_name << " file path :" << attachment[i].attachment_path);
1122                                 int attachmentId = attachment[i].attachment_id;
1123
1124 //                              stream << attachmentId;
1125 //                              int error = email_delete_attachment(m_mail->mail_id, (const char*)(stream.str()).c_str());
1126                                 int error = email_delete_attachment(attachmentId);
1127                                 if (EMAIL_ERROR_NONE != error) {
1128                                     LogDebug("Error Num = " << error);
1129                                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1130                                              "Error while adding attachment. [" << error << "]");
1131                                 }
1132                                 stream.str("");
1133                         }
1134
1135                         if ( attachment )
1136                         {
1137                                 error = email_free_attachment_data(&attachment, attachmentCount);
1138                                 if (EMAIL_ERROR_NONE != error) {
1139                                         ThrowMsg( WrtDeviceApis::Commons::PlatformException, " attachment_data free error! ");
1140                                 }
1141                         }
1142
1143                 }
1144                 
1145                 //set Attachment
1146                 std::size_t attachmentSize = getAttachmentsCount();
1147                 LogDebug("update attachments, attachmentSize=" << attachmentSize);
1148                 if (attachmentSize > 0) {
1149 //                      email_attachment_info_t* attachment_info = NULL;
1150                         email_attachment_data_t* attachment_info = NULL;
1151                         for (std::size_t i = 0; i < attachmentSize; ++i) {
1152                                 IAttachmentPtr att = getAttachment(i);
1153                                 if (!att) {
1154                                         continue;
1155                                 }
1156
1157                                 //copy attachment file
1158                                 std::stringstream cp_cmd;
1159                                 char buf[] = "/tmp/XXXXXX";
1160                                 int i = mkstemp(buf);
1161
1162                                 cp_cmd << COMMAND_NAME;
1163                                 cp_cmd << " " << COMMAND_SWITCH_RECURSIVE;
1164                                 cp_cmd << " \"" << att->getFullPath() << "\"";
1165                                 cp_cmd << " \"" << buf << "\"";
1166
1167 //                              attachment_info = EmailService::alloc<email_attachment_info_t>();
1168                                 attachment_info = EmailService::alloc<email_attachment_data_t>();                                       
1169                                 attachment_info->attachment_name = String::strdup(att->getShortName());
1170                                 attachment_info->attachment_path = String::strdup( buf );
1171 //                              attachment_info->next = NULL;
1172                                 attachment_info->save_status = true;
1173
1174                                 LogDebug("Copy Command=" << cp_cmd.str());
1175
1176                                 int result = system(cp_cmd.str().c_str());
1177                                 if (-1 != result) {
1178                                         if (0 != WIFEXITED(result)) {
1179                                                 if (0 != WEXITSTATUS(result)) {
1180                                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Command failed.");
1181                                                 }
1182                                         } else {
1183                                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1184                                                 "Command terminated abnormally.");
1185                                         }
1186                                 } else {
1187                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Couldn't launch command.");
1188                                 }
1189
1190                                 LogDebug("add Attachment");
1191                                 int error = email_add_attachment(m_mail->mail_id, attachment_info);
1192                                 if (EMAIL_ERROR_NONE != error) {
1193                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1194                                      "Error while adding attachment. [" << error << "]");
1195                                 }
1196                                 else 
1197                                 {       
1198                                         LogDebug(" attachment id : " << attachment_info->attachment_id);                                
1199                                                 //IMessagePtr msg = DPL::DynamicPointerCast<IMessage>(this);
1200                                         att->setDownloaded(true);
1201                                         att->setAttachmentID(attachment_info->attachment_id);
1202                                         att->setMessage(SharedFromThis());
1203                                         att->setNth(i+1);
1204                                 }
1205                                 
1206                                 if (attachment_info)
1207                                         EmailService::freeAttachment(attachment_info);
1208                         }       
1209                         
1210                 }
1211         
1212         } 
1213         Catch(WrtDeviceApis::Commons::PlatformException) {
1214            if (attachment) 
1215            {
1216                 int error = email_free_attachment_data(&attachment, attachmentCount);
1217                 if (EMAIL_ERROR_NONE != error) {
1218                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1219                                      "Error while adding attachment data [" << error << "]");
1220                 }
1221
1222                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
1223                                      "Error attachment Update");
1224            }
1225         }
1226
1227     LOG_EXIT
1228 }
1229
1230 void Email::updatePriority()
1231 {
1232     LOG_ENTER
1233
1234     if (isPriorityValid()) { return; }
1235
1236     if (!m_mail) {
1237         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
1238     }
1239
1240     m_mail->priority = EmailConverter::toMailPriority( getPriority());
1241     setPriorityValid(true);
1242
1243     LOG_EXIT
1244 }
1245
1246 int Email::getIntId() const
1247 {
1248     return convertId(getIdRef());
1249 }
1250
1251 }
1252 }
1253 }