/*
 * UosSylph -- E-Mail client library
 * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co.,Ltd.
 *
 * Author:     shuiqucheng<shuiqucheng@uniontech.com>
 *
 * Maintainer: shuiqucheng<shuiqucheng@uniontech.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef __UOSPROCMSG_H__
#define __UOSPROCMSG_H__

#include "libsylph/procmsg.h"

typedef MsgInfo UosMsgInfo;
typedef MsgFlags UosMsgFlags;
typedef MsgFileInfo UosMsgFileInfo;
typedef MsgEncryptInfo UosMsgEncryptInfo;

#include "uosprocmime.h"
#include "uosfolder.h"
#include "uosutils.h"

typedef DataOpenMode UosDataOpenMode;
#define UosDATA_READ DATA_READ
#define UosDATA_WRITE DATA_WRITE
#define UosDATA_APPEND DATA_APPEND

#define UOSMSG_NEW MSG_NEW
#define UOSMSG_UNREAD MSG_UNREAD
#define UOSMSG_MARKED MSG_MARKED
#define UOSMSG_DELETED MSG_DELETED
#define UOSMSG_REPLIED MSG_REPLIED
#define UOSMSG_FORWARDED MSG_FORWARDED

#define UOSMSG_CLABEL_SBIT MSG_CLABEL_SBIT
#define UOSMAKE_MSG_CLABEL(h, m, l) MAKE_MSG_CLABEL(h, m, l)

#define UOSMSG_CLABEL_NONE MSG_CLABEL_NONE
#define UOSMSG_CLABEL_1 MSG_CLABEL_1
#define UOSMSG_CLABEL_2 MSG_CLABEL_2
#define UOSMSG_CLABEL_3 MSG_CLABEL_3
#define UOSMSG_CLABEL_4 MSG_CLABEL_4
#define UOSMSG_CLABEL_5 MSG_CLABEL_5
#define UOSMSG_CLABEL_6 MSG_CLABEL_6
#define UOSMSG_CLABEL_7 MSG_CLABEL_7

#define UOSMSG_CLABEL_ORANGE MSG_CLABEL_ORANGE
#define UOSMSG_CLABEL_RED MSG_CLABEL_RED
#define UOSMSG_CLABEL_PINK MSG_CLABEL_PINK
#define UOSMSG_CLABEL_SKYBLUE MSG_CLABEL_SKYBLUE
#define UOSMSG_CLABEL_BLUE MSG_CLABEL_BLUE
#define UOSMSG_CLABEL_GREEN MSG_CLABEL_GREEN
#define UOSMSG_CLABEL_BROWN MSG_CLABEL_BROWN

#define UOSMSG_RESERVED MSG_RESERVED

#define UOSMSG_CLABEL_FLAG_MASK MSG_CLABEL_FLAG_MASK

typedef MsgPermFlags UosMsgPermFlags;

#define UOSMSG_MOVE MSG_MOVE
#define UOSMSG_COPY MSG_COPY
#define UOSMSG_QUEUED MSG_QUEUED
#define UOSMSG_DRAFT MSG_DRAFT
#define UOSMSG_ENCRYPTED MSG_ENCRYPTED
#define UOSMSG_IMAP MSG_IMAP
#define UOSMSG_NEWS MSG_NEWS
#define UOSMSG_SIGNED MSG_SIGNED
#define UOSMSG_MIME_HTML MSG_MIME_HTML
#define UOSMSG_FLAG_CHANGED MSG_FLAG_CHANGED
#define UOSMSG_CACHED MSG_CACHED
#define UOSMSG_MIME MSG_MIME
#define UOSMSG_INVALID MSG_INVALID
#define UOSMSG_RECEIVED MSG_RECEIVED

#define UOSMSG_CACHED_FLAG_MASK MSG_CACHED_FLAG_MASK

typedef MsgTmpFlags UosMsgTmpFlags;

#define UOSMSG_SET_FLAGS(msg, flags) MSG_SET_FLAGS(msg, flags)
#define UOSMSG_UNSET_FLAGS(msg, flags) MSG_UNSET_FLAGS(msg, flags)
#define UOSMSG_SET_PERM_FLAGS(msg, flags) MSG_SET_PERM_FLAGS(msg, flags)
#define UOSMSG_SET_TMP_FLAGS(msg, flags) MSG_SET_TMP_FLAGS(msg, flags)
#define UOSMSG_UNSET_PERM_FLAGS(msg, flags) MSG_UNSET_PERM_FLAGS(msg, flags)
#define UOSMSG_UNSET_TMP_FLAGS(msg, flags) MSG_UNSET_TMP_FLAGS(msg, flags)

#define UOSMSG_IS_NEW(msg) MSG_IS_NEW(msg)
#define UOSMSG_IS_UNREAD(msg) MSG_IS_UNREAD(msg)
#define UOSMSG_IS_MARKED(msg) MSG_IS_MARKED(msg)
#define UOSMSG_IS_DELETED(msg) MSG_IS_DELETED(msg)
#define UOSMSG_IS_REPLIED(msg) MSG_IS_REPLIED(msg)
#define UOSMSG_IS_FORWARDED(msg) MSG_IS_FORWARDED(msg)

#define UOSMSG_GET_COLORLABEL(msg) MSG_GET_COLORLABEL(msg)
#define UOSMSG_GET_COLORLABEL_VALUE(msg) MSG_GET_COLORLABEL_VALUE(msg)
#define UOSMSG_SET_COLORLABEL_VALUE(msg, val) MSG_SET_COLORLABEL_VALUE(msg, val)

#define UOSMSG_IS_MOVE(msg) MSG_IS_MOVE(msg)
#define UOSMSG_IS_COPY(msg) MSG_IS_COPY(msg)

#define UOSMSG_IS_QUEUED(msg) MSG_IS_QUEUED(msg)
#define UOSMSG_IS_DRAFT(msg) MSG_IS_DRAFT(msg)
#define UOSMSG_IS_ENCRYPTED(msg) MSG_IS_ENCRYPTED(msg)
#define UOSMSG_IS_IMAP(msg) MSG_IS_IMAP(msg)
#define UOSMSG_IS_NEWS(msg) MSG_IS_NEWS(msg)
#define UOSMSG_IS_SIGNED(msg) MSG_IS_SIGNED(msg)
#define UOSMSG_IS_MIME_HTML(msg) MSG_IS_MIME_HTML(msg)
#define UOSMSG_IS_FLAG_CHANGED(msg) MSG_IS_FLAG_CHANGED(msg)
#define UOSMSG_IS_CACHED(msg) MSG_IS_CACHED(msg)
#define UOSMSG_IS_MIME(msg) MSG_IS_MIME(msg)
#define UOSMSG_IS_INVALID(msg) MSG_IS_INVALID(msg)
#define UOSMSG_IS_RECEIVED(msg) MSG_IS_RECEIVED(msg)

#define UOSWRITE_CACHE_DATA_INT(n, fp) WRITE_CACHE_DATA_INT(n, fp)

#define UOSWRITE_CACHE_DATA(data, fp) WRITE_CACHE_DATA(data, fp)

typedef CalendarFlag UosCalendarFlag;
#define UosCALENDAR_NONE CALENDAR_NONE
#define UosCALENDAR_REQUEST CALENDAR_REQUEST
#define UosCALENDAR_Reply CALENDAR_Reply

typedef DecryptMessageFunc UosDecryptMessageFunc;

GHashTable *uos_procmsg_msg_hash_table_create(GSList *mlist);
void uos_procmsg_msg_hash_table_append(GHashTable *msg_table,
                                       GSList *mlist);
GHashTable *uos_procmsg_to_folder_hash_table_create(GSList *mlist);

gint uos_procmsg_read_cache_data_str(FILE *fp,
                                     gchar **str);

GSList *uos_procmsg_read_cache(UosFolderItem *item,
                               gboolean scan_file);
void uos_procmsg_set_flags(GSList *mlist,
                           UosFolderItem *item);
void uos_procmsg_mark_all_read(UosFolderItem *item);
GSList *uos_procmsg_sort_msg_list(GSList *mlist,
                                  UosFolderSortKey sort_key,
                                  UosFolderSortType sort_type);
gint uos_procmsg_get_last_num_in_msg_list(GSList *mlist);
void uos_procmsg_msg_list_free(GSList *mlist);

void uos_procmsg_write_cache(UosMsgInfo *msginfo,
                             FILE *fp);
void uos_procmsg_write_flags(UosMsgInfo *msginfo,
                             FILE *fp);
void uos_procmsg_write_cache_list(UosFolderItem *item,
                                  GSList *mlist);
void uos_procmsg_write_flags_list(UosFolderItem *item,
                                  GSList *mlist);
void uos_procmsg_write_flags_for_multiple_folders(GSList *mlist);

void uos_procmsg_flaginfo_list_free(GSList *flaglist);

void uos_procmsg_flush_mark_queue(UosFolderItem *item,
                                  FILE *fp);
void uos_procmsg_add_mark_queue(UosFolderItem *item,
                                gint num,
                                MsgFlags flags);
void uos_procmsg_flush_cache_queue(UosFolderItem *item,
                                   FILE *fp);
void uos_procmsg_add_cache_queue(UosFolderItem *item,
                                 gint num,
                                 MsgInfo *msginfo);

gboolean uos_procmsg_flush_folder(UosFolderItem *item);
void uos_procmsg_flush_folder_foreach(GHashTable *folder_table);

void uos_procmsg_add_flags(UosFolderItem *item,
                           gint num,
                           UosMsgFlags flags);

void uos_procmsg_get_mark_sum(UosFolderItem *item,
                              gint *new1,
                              gint *unread,
                              gint *total,
                              gint *min,
                              gint *max,
                              gint first);

FILE *uos_procmsg_open_data_file(const gchar *file,
                                 guint version,
                                 UosDataOpenMode mode,
                                 gchar *buf,
                                 size_t buf_size);

FILE *uos_procmsg_open_cache_file(UosFolderItem *item,
                                  UosDataOpenMode mode);
FILE *uos_procmsg_open_mark_file(UosFolderItem *item,
                                 UosDataOpenMode mode);

void uos_procmsg_clear_cache(UosFolderItem *item);
void uos_procmsg_clear_mark(UosFolderItem *item);

GNode *uos_procmsg_get_thread_tree(GSList *mlist);
guint uos_procmsg_get_thread_date(GNode *node);

gint uos_procmsg_move_messages(GSList *mlist, gboolean bcachepool);
gint uos_procmsg_copy_messages(GSList *mlist);

gint uos_procmsg_add_messages_from_queue(UosFolderItem *dest,
                                         GSList *mlist,
                                         gboolean is_move);

gchar *uos_procmsg_get_message_file_path(UosMsgInfo *msginfo);
gchar *uos_procmsg_get_message_file(UosMsgInfo *msginfo);
GSList *uos_procmsg_get_message_file_list(GSList *mlist);
void uos_procmsg_message_file_list_free(GSList *file_list);
FILE *uos_procmsg_open_message(UosMsgInfo *msginfo);

void uos_procmsg_set_decrypt_message_func(UosDecryptMessageFunc func);
void uos_procmsg_set_auto_decrypt_message(gboolean enabled);
FILE *uos_procmsg_open_message_decrypted(UosMsgInfo *msginfo,
                                         UosMimeInfo **mimeinfo);

gboolean uos_procmsg_msg_exist(UosMsgInfo *msginfo);

gboolean uos_procmsg_trash_messages_exist(void);
void uos_procmsg_empty_trash(UosFolderItem *trash);
void uos_procmsg_empty_all_trash(void);

void uos_procmsg_remove_all_cached_messages(UosFolder *folder);

gint uos_procmsg_save_to_outbox(UosFolderItem *outbox,
                                const gchar *file);
void uos_procmsg_print_message(UosMsgInfo *msginfo,
                               const gchar *cmdline,
                               gboolean all_headers);
void uos_procmsg_print_message_part(UosMsgInfo *msginfo,
                                    UosMimeInfo *partinfo,
                                    const gchar *cmdline,
                                    gboolean all_headers);

gint uos_procmsg_save_message_as_text(UosMsgInfo *msginfo,
                                      const gchar *dest,
                                      const gchar *encoding,
                                      gboolean all_headers);

gint uos_procmsg_concat_partial_messages(GSList *mlist,
                                         const gchar *file);

UosMsgInfo *uos_procmsg_get_msginfo(UosFolderItem *item,
                                    gint num);

UosMsgInfo *uos_procmsg_msginfo_copy(UosMsgInfo *msginfo);
UosMsgInfo *uos_procmsg_msginfo_get_full_info(UosMsgInfo *msginfo);
gboolean uos_procmsg_msginfo_equal(UosMsgInfo *msginfo_a,
                                   UosMsgInfo *msginfo_b);
void uos_procmsg_msginfo_free(UosMsgInfo *msginfo);

gint uos_procmsg_cmp_msgnum_for_sort(gconstpointer a,
                                     gconstpointer b);
//读取备份文件新增的函数
GSList *uos_procmsg_read_backup_cache(UosFolderItem *item, gboolean scanfile);
//写入备份文件
FILE *uos_procmsg_open_backup_file(UosFolderItem *item, guint version, UosDataOpenMode mode, int backup_type);
//读取并设置备份数据的标记信息
void uos_procmsg_set_backup_flags(GSList *mlist, UosFolderItem *item);

//写入备份文件操作
void uos_procmsg_write_backup_cache(UosMsgInfo *msginfo, FILE *fp);
void uos_procmsg_write_backup_flags(UosMsgInfo *msginfo, FILE *fp);

//多线程文件读写锁
//cache file
void uos_cache_file_thread_mutext_trylock(void);
void uos_cache_file_thread_mutext_unlock(void);

//mark file
void uos_mark_file_thread_mutext_trylock(void);
void uos_mark_file_thread_mutext_unlock(void);

void uos_file_thread_mutext_destroy(void);
#endif /* __UOSPROCMSG_H__ */
