#pragma once

/// @file
/// @brief Определение функций API для работы с конвертами ПО Деловая почта
///
/// @copyright Copyright 2021 InfoTeCS.

#include <stdint.h>
#include <stddef.h>
#include <time.h>

#if defined( _WIN32 )
#    define BmApiExport
#else
#    if ( __GNUC__ >= 4 ) || defined( __clang__ )
#        define BmApiExport __attribute__( ( visibility( "default" ) ) )
#    else
#        define BmApiExport
#    endif
#endif

enum BusinessMailApiVersion
{
    BUSINESS_MAIL_API_VERSION = 1
};

/// @brief Тип конверта
enum VpnBusinessMailEnvelopeType
{
    BmLetter = 0, ///> Письмо
    BmReceipt = 1 ///> Квитанция
};

/// @brief Тип получателя письма
enum VpnBusinessMailRecipientType
{
    BmRecipientTo = 0,    ///> Получатель из поля "Кому"
    BmRecipientCopy = 1,  ///> Получатель из поля "Копия"
    BmRecipientHidden = 2 ///> Получатель из поля "Скрытая копия"
};

/// @brief Результат выполнения команды
typedef struct
{
    /// @brief Код возврата функций (0 - успешное завершение)
    uint32_t code;

    /// @brief Сообщение об ошибке (пустое при успешном завершении)
    /// @remarks Не требует освобождения памяти. Сообщение хранится до следующего вызова команды.
    const char* message;
} BusinessMailApiReturnCode;

///@brief Данные содержимого письма, предназначенного для ПО Деловая почта
typedef struct
{
    uint32_t sender;        ///> ID узла отправителя
    uint32_t* recipientIds; ///> ID узлов всех получателей письма (для входящего письма текущий получатель 1й в списке)
    enum VpnBusinessMailRecipientType* recipientTypes; ///> Тип получателей
    size_t recipientsCount;                            ///> Количество получателей
    const char* regNumber;                             ///> Регистрационный номер письма
    const char* subject;                               ///> Тема письма
    const char* message;                               ///> Сообщение
    time_t creationTime;                               ///> Дата создания
    time_t sendTime;                                   ///> Дата отправки
    const char** attachmentPaths;                      ///> Пути до файлов вложений
    const char** attachmentNames;                      ///> Имена файлов вложений
    size_t attachmentsCount;                           ///> Количество файлов вложений
} VpnBusinessMailLetterData;

///@brief Данные содержимого квитанции, предназначенной для ПО Деловая почта
typedef struct
{
    uint32_t sender;        ///> ID узла отправителя
    uint32_t recipient;     ///> ID узла получателя
    uint8_t type;           ///> Тип квитанции
    const char* letterName; ///> Имя конверта письма
    time_t creationTime;    ///> Дата создания
} VpnBusinessMailReceiptData;

/// @brief Получить список конвертов, предназначенных для ПО Деловая почта
/// @param[in] type - тип конверта
/// @param[out] envelopes - список конвертов
/// @param[out] size - количество конвертов
/// @remarks Память для envelopes выделяется динамически и должна быть освобождена самостоятельно
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *GetBusinessMailEnvelopes )( enum VpnBusinessMailEnvelopeType type,
                                                                 char*** envelopes,
                                                                 size_t* size );

/// @brief Удалить конверт для ПО Деловая почта
/// @param[in] envelope - имя конверта
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *RemoveBusinessMailEnvelope )( const char* envelope );

/// @brief Распаковать письмо, предназначенное для ПО Деловая почта
/// @param[in] envelope - имя конверта
/// @param[in] attachmentsDir - путь к директории, куда необходимо скопировать вложения, если они есть
/// @param[out] bmData - содержимое письма
/// @remarks Память для bmData выделяется динамически и должна быть освобождена с помощью ReleaseVpnBusinessMailLetterData( bmData )
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *UnpackBusinessMailLetter )( const char* envelope,
                                                                 const char* attachmentsDir,
                                                                 VpnBusinessMailLetterData** bmData );

/// @brief Распаковать квитанцию, предназначенную для ПО Деловая почта
/// @param[in] envelope - имя конверта
/// @param[out] bmData - содержимое квитанции
/// @remarks Память для bmData выделяется динамически и должна быть освобождена с помощью ReleaseVpnBusinessMailReceiptData( bmData )
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *UnpackBusinessMailReceipt )( const char* envelope,
                                                                  VpnBusinessMailReceiptData** bmData );

/// @brief Сформировать и отправить письмо, предназначенное для ПО Деловая почта
/// @param[in] bmData - содержимое конверта
/// @param[out] envelopes - имена конвертов (отсортированы в порядке следования получателей)
/// @param[out] size - количество конвертов
/// @remarks Память для envelopes выделяется динамически и должна быть освобождена самостоятельно
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *PackBusinessMailLetter )( VpnBusinessMailLetterData* bmData,
                                                               char*** envelopes,
                                                               size_t* size );

/// @brief Сформировать и отправить квитанцию, предназначенную для ПО Деловая почта
/// @param[in] bmData - содержимое конверта
/// @param[out] envelope - имя конверта
/// @remarks Память для envelope выделяется динамически и должна быть освобождена самостоятельно
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *PackBusinessMailReceipt )( VpnBusinessMailReceiptData* bmData, char** envelope );

/// @brief Освободить память, выделенную для содержимого письма
/// @param[in] bmData - содержимое конверта
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *ReleaseVpnBusinessMailLetterData )( VpnBusinessMailLetterData* bmData );

/// @brief Освободить память, выделенную для содержимого квитанции
/// @param[in] bmData - содержимое конверта
/// @return Результат выполнения команды
typedef BusinessMailApiReturnCode ( *ReleaseVpnBusinessMailReceiptData )( VpnBusinessMailReceiptData* bmData );

/// @brief Функции API для работы с конвертами ПО Деловая почта (описание функций выше)
typedef struct
{
    // API_VERSION_1
    GetBusinessMailEnvelopes getBusinessMailEnvelopes;
    RemoveBusinessMailEnvelope removeBusinessMailEnvelope;
    UnpackBusinessMailLetter unpackBusinessMailLetter;
    UnpackBusinessMailReceipt unpackBusinessMailReceipt;
    PackBusinessMailLetter packBusinessMailLetter;
    PackBusinessMailReceipt packBusinessMailReceipt;
    ReleaseVpnBusinessMailLetterData releaseVpnBusinessMailLetterData;
    ReleaseVpnBusinessMailReceiptData releaseVpnBusinessMailReceiptData;
} ItcsBusinessMailApi;

#ifdef __cplusplus
extern "C" {
#endif

/// @brief Получить текущую версию API для работы с конвертами ПО Деловая почта
/// @remarks При обновлении версии API рекомендуется проверить совместимость, иначе работоспособность не гарантируется
/// @return Текущая версия API для работы с конвертами ПО Деловая почта
BmApiExport uint32_t GetBusinessMailApiVersion();

/// @brief Получить указатель на структуру API для работы с конвертами ПО Деловая почта
/// @return Указатель на структуру API для работы с конвертами ПО Деловая почта
BmApiExport ItcsBusinessMailApi* GetBusinessMailApi();

#ifdef __cplusplus
}
#endif
