/*
 * 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 __UOSFOLDER_H__
#define __UOSFOLDER_H__

#include "libsylph/folder.h"

typedef Folder UosFolder;
typedef FolderClass UosFolderClass;

typedef LocalFolder UosLocalFolder;
typedef RemoteFolder UosRemoteFolder;

typedef FolderItem UosFolderItem;

#define UOSFOLDER(obj) ((Folder *)obj)
#define UOSFOLDER_CLASS(obj) (FOLDER(obj)->klass)
#define UOSFOLDER_TYPE(obj) (FOLDER(obj)->klass->type)

#define UOSLOCAL_FOLDER(obj) ((LocalFolder *)obj)
#define UOSREMOTE_FOLDER(obj) ((RemoteFolder *)obj)

#define UOSFOLDER_IS_LOCAL(obj) (FOLDER_TYPE(obj) == F_MH || FOLDER_TYPE(obj) == F_MBOX || FOLDER_TYPE(obj) == F_MAILDIR)
#define UOSFOLDER_IS_REMOTE(obj) (FOLDER_TYPE(obj) == F_IMAP || FOLDER_TYPE(obj) == F_NEWS)

#define UOSFOLDER_ITEM(obj) ((FolderItem *)obj)

#define UOSFOLDER_ITEM_CAN_ADD(obj) \
    ((obj) && FOLDER_ITEM(obj)->folder && FOLDER_ITEM(obj)->path && (FOLDER_IS_LOCAL(FOLDER_ITEM(obj)->folder) || FOLDER_TYPE(FOLDER_ITEM(obj)->folder) == F_IMAP) && !FOLDER_ITEM(obj)->no_select)

#define UOSFOLDER_ITEM_IS_SENT_FOLDER(obj) ((obj) && ((obj)->stype == F_OUTBOX || (obj)->stype == F_DRAFT || (obj)->stype == F_QUEUE))

typedef FolderType UosFolderType;
#define UosF_MH F_MH
#define UosF_MBOX F_MBOX
#define UosF_MAILDIR F_MAILDIR
#define UosF_IMAP F_IMAP
#define UosF_NEWS F_NEWS
#define UosF_POP F_POP
#define UosF_UNKNOWN F_UNKNOWN

typedef BackupFile UosBackupFile;
#define UosBackup_Cache Backup_Cache
#define UosBackup_Mark Backup_Mark

typedef SpecialFolderItemType UosSpecialFolderItemType;
#define UosF_NORMAL F_NORMAL
#define UosF_INBOX F_INBOX
#define UosF_OUTBOX F_OUTBOX
#define UosF_DRAFT F_DRAFT
#define UosF_QUEUE F_QUEUE
#define UosF_TRASH F_TRASH
#define UosF_JUNK F_JUNK
#define UosF_VIRTUAL F_VIRTUAL
#define UosF_IMPORTANT F_IMPORTANT
#define UosF_UNREAD F_UNREAD
#define UosF_ARCHIVE F_ARCHIVE

typedef FolderSortKey UosFolderSortKey;
#define UosSORT_BY_NONE SORT_BY_NONE
#define UosSORT_BY_NUMBER SORT_BY_NUMBER
#define UosSORT_BY_SIZE SORT_BY_SIZE
#define UosSORT_BY_DATE SORT_BY_DATE
#define UosSORT_BY_TDATE SORT_BY_TDATE
#define UosSORT_BY_FROM SORT_BY_FROM
#define UosSORT_BY_SUBJECT SORT_BY_SUBJECT
#define UosSORT_BY_SCORE SORT_BY_SCORE
#define UosSORT_BY_LABEL SORT_BY_LABEL
#define UosSORT_BY_MARK SORT_BY_MARK
#define UosSORT_BY_UNREAD SORT_BY_UNREAD
#define UosSORT_BY_MIME SORT_BY_MIME
#define UosSORT_BY_TO SORT_BY_TO

typedef FolderSortType UosFolderSortType;
#define UosSORT_ASCENDING SORT_ASCENDING
#define UosSORT_DESCENDING SORT_DESCENDING

typedef FolderUIFunc UosFolderUIFunc;
typedef FolderUIFunc2 UosFolderUIFunc2;
typedef FolderUIFunc3 UosFolderUIFunc3;
typedef FolderDestroyNotify UosFolderDestroyNotify;

#include "uosprefs_account.h"
#include "uossession.h"
#include "uosprocmsg.h"
#include "uosutils.h"

//typedef MsgInfo UosMsgInfo;
//typedef MsgFlags UosMsgFlags;
//typedef MsgFileInfo UosMsgFileInfo;
//typedef MsgEncryptInfo UosMsgEncryptInfo;
//typedef MsgPermFlags UosMsgPermFlags;

UosFolder *uos_folder_new(UosFolderType type,
                   const gchar *name,
                   const gchar *path);
void uos_folder_local_folder_init(UosFolder *folder,
                              const gchar *name,
                              const gchar *path);
void uos_folder_remote_folder_init(UosFolder *folder,
                               const gchar *name,
                               const gchar *path);

void uos_folder_destroy(UosFolder *folder);
void uos_folder_clear(UosFolder *folder);
void uos_folder_local_folder_destroy(UosLocalFolder *lfolder);
void uos_folder_remote_folder_destroy(UosRemoteFolder *rfolder);

gint uos_folder_remote_folder_destroy_all_sessions(void);

gboolean uos_folder_remote_folder_is_session_active(UosRemoteFolder *rfolder);
gboolean uos_folder_remote_folder_active_session_exist(void);

gint uos_folder_scan_tree(UosFolder *folder);
gint uos_folder_create_tree(UosFolder *folder);

UosFolderItem *uos_folder_item_new(const gchar *name,
                            const gchar *path);
void uos_folder_item_append(UosFolderItem *parent,
                        UosFolderItem *item);
UosFolderItem *uos_folder_item_copy(UosFolderItem *item);
void uos_folder_item_remove(UosFolderItem *item);
void uos_folder_item_remove_children(UosFolderItem *item);
void uos_folder_item_destroy(UosFolderItem *item);

gint uos_folder_item_compare(UosFolderItem *item_a,
                         UosFolderItem *item_b);

UosFolderUIFunc2 uos_folder_get_ui_func2(UosFolder *folder);
gboolean uos_folder_call_ui_func2(UosFolder *folder,
                              UosFolderItem *item,
                              guint count,
                              guint total);

void uos_folder_set_name(UosFolder *folder,
                     const gchar *name);
void uos_folder_tree_destroy(UosFolder *folder);

void uos_folder_add(UosFolder *folder);

GList *uos_folder_get_list(void);
void uos_folder_list_free(void);
gint uos_folder_read_list(void);
void uos_folder_write_list(void);

gchar *uos_folder_get_status(GPtrArray *folders,
                         gboolean full);

UosFolder *uos_folder_find_from_path(const gchar *path);
UosFolder *uos_folder_find_from_name(const gchar *name,
                              UosFolderType type);
UosFolderItem *uos_folder_find_item_from_path(const gchar *path);
UosFolderItem *uos_folder_find_child_item_by_name(UosFolderItem *item,
                                           const gchar *name);
gchar *uos_folder_get_identifier(UosFolder *folder);
gchar *uos_folder_item_get_identifier(UosFolderItem *item);
UosFolderItem *uos_folder_find_item_from_identifier(const gchar *identifier);
UosFolderItem *uos_folder_find_item_and_num_from_id(const gchar *identifier,
                                             gint *num);

UosFolder *uos_folder_get_default_folder(void);
UosFolderItem *uos_folder_get_default_inbox(void);
UosFolderItem *uos_folder_get_default_outbox(void);
UosFolderItem *uos_folder_get_default_draft(void);
UosFolderItem *uos_folder_get_default_queue(void);
UosFolderItem *uos_folder_get_default_trash(void);
UosFolderItem *uos_folder_get_default_junk(void);

gboolean uos_folder_item_is_trash(UosFolderItem *item);

UosFolderItem *uos_folder_get_junk(UosFolder *folder);
void uos_folder_set_junk(UosFolder *folder,
                     UosFolderItem *item);

void uos_folder_set_missing_folders(void);
void uos_folder_unref_account_all(UosPrefsAccount *account);

gchar *uos_folder_get_path(UosFolder *folder);
gchar *uos_folder_item_get_path(UosFolderItem *item);

gint uos_folder_item_scan(UosFolderItem *item);
void uos_folder_item_scan_foreach(GHashTable *table);
void uos_folder_item_scan_foreach_cache(GHashTable *table); //add by shui
GSList *uos_folder_item_get_msg_list(UosFolderItem *item,
                                 gboolean use_cache);
GSList *uos_folder_item_get_uncached_msg_list(UosFolderItem *item);
/* return value is filename encoding */
gchar *uos_folder_item_fetch_msg(UosFolderItem *item,
                             gint num);
gint uos_folder_fetch_all_msg(UosFolder *folder, gint *newdownload, gint *newindexdownload);
gint uos_folder_item_fetch_all_msg_self(UosFolderItem *item, gint *newdownload);
gint uos_folder_item_fetch_all_msg(UosFolderItem *item);
UosMsgInfo *uos_folder_item_get_msginfo(UosFolderItem *item,
                                 gint num);
gint uos_folder_item_add_msg(UosFolderItem *dest,
                         const gchar *file,
                         UosMsgFlags *flags,
                         gboolean remove_source);
gint uos_folder_item_add_msgs(UosFolderItem *dest,
                          GSList *file_list,
                          gboolean remove_source,
                          gint *first);
gint uos_folder_item_add_msg_msginfo(UosFolderItem *dest,
                                 UosMsgInfo *msginfo,
                                 gboolean remove_source);
gint uos_folder_item_add_msgs_msginfo(UosFolderItem *dest,
                                  GSList *msginfo_list,
                                  gboolean remove_source,
                                  gint *first);
gint uos_folder_item_move_msg(UosFolderItem *dest,
                          UosMsgInfo *msginfo);
gint uos_folder_item_move_msgs(UosFolderItem *dest,
                           GSList *msglist);
gint uos_folder_item_copy_msg(UosFolderItem *dest,
                          UosMsgInfo *msginfo);
gint uos_folder_item_copy_msgs(UosFolderItem *dest,
                           GSList *msglist);
gint uos_folder_item_remove_msg(UosFolderItem *item,
                            UosMsgInfo *msginfo);
gint uos_folder_item_remove_msgs(UosFolderItem *item,
                             GSList *msglist);
gint uos_folder_item_remove_all_msg(UosFolderItem *item);

gboolean uos_folder_item_is_msg_changed(UosFolderItem *item,
                                    UosMsgInfo *msginfo);

gchar *uos_folder_item_get_cache_file(UosFolderItem *item);
gchar *uos_folder_item_get_mark_file(UosFolderItem *item);

gint uos_folder_item_close(UosFolderItem *item);
/*add shangxiudong return .backup_cache file*/
gchar *uos_folder_item_get_backup_file(UosFolderItem *item, int backup_type);

void uos_delete_backup_file(gchar *file);

#endif /* __UOSFOLDER_H__ */
