#ifndef CLOUD_API_HEADER_H
#define CLOUD_API_HEADER_H

#include "reader/support.h"

#if !defined( _CLOUD_DECL )
#define _CLOUD_DECL
#endif /* !defined( _CLOUD_DECL ) */

#if defined( __cplusplus )
extern "C" {
#endif /* defined( __cplusplus ) */

DWORD LoadCloudLibrary();

typedef void* TDssCertificatesEnumContext;
typedef void* TCloudServerEnumCtx;

typedef struct {
    const char* szUnique;	// уникальное имя сервера
    const char* szAuthURL;	// адрес сервера аутентификации, м.б. NULL, игнорируется, если уже есть регистрация с szUnique
    const char* szRestURL;	// адрес сервера подписи, м.б. NULL, игнорируется, если уже есть регистрация с szUnique
    const char* szUsername;	// логин для аутентификации, м.б. NULL
    const char* szPassword;	// пароль для аутентификации, м.б. NULL
    const TCHAR* szDescription;	// описание сервера, м.б. NULL
    BOOL bTestService;		// признак, что сервер является тестовым
    const char* szDocStoreURL;	// адрес сервера обработки документов, м.б. NULL, игнорируется, если уже есть регистрация с szUnique
} TDssServerInfo;

static const unsigned DSS_SERVER_INFO_VERSION_0 = 0;	// szUnique, szAuthURL, szRestURL, szUsername, szPassword
static const unsigned DSS_SERVER_INFO_VERSION_1 = 1;	// + szDescription, bTestService
static const unsigned DSS_SERVER_INFO_VERSION_2 = 2;	// + szDocStoreURL

typedef struct {
    BYTE* certificate;              // байтовый массив с сертификатом
    size_t certificate_length;      // длина массива с сертификатом
    unsigned certificate_id;        // идентификатор сертификата на DSS
    DWORD key_spec;                 // тип ключа (AT_KEYEXCHANGE или AT_SIGNATURE)
    DWORD permissions;              // разрешения ключа
    BYTE* extensions;               // расширения ключевого контейнера (сроки действия и цепочки)
    size_t extensions_length;       // длина расширений ключевого контейнера
    char* szFriendlyName;           // дружественное имя контейнера
    size_t szFriendlyNameMaxLength; // длина дружественного имени
} TDssCertificateInfo;

/*
* Установить сертификат и его свойства в хранилище сертификатов.
*/
_CLOUD_DECL DWORD SetCloudCertificateToStore(
    const TDssServerInfo* serverInfo,           // настройки сервера для установки
    const TDssCertificateInfo* certificateInfo, // свойства сертификата, полученные с сервера
    const char* szContName,                     // имя контейнера; по которому будет происходить адресация к контейнеру;
		                                // если NULL; генерируется автоматически
    BOOL isLM,                                  // признак необходимости установки сертификата в локальное хранилище компьютера
    const WCHAR *wszProvName,                   //имя провайдера, м.б. NULL
    DWORD dwProvType                            //тип провайдера, м.б. 0
);

/*
* Получить контекст перечисления сертификатов на DSS.
* TDssCertificatesEnumContext должен быть обязательно освобожден с помощью DssCertificatesEnumClose.
*/
_CLOUD_DECL DWORD DssCertificatesEnumOpen(
    const TDssServerInfo* serverInfo,           // настройки сервера для установки
    TDssCertificatesEnumContext *enumContextPtr // выходной параметр с контекстом перечисления
);

/*
* Получить следующий сертификат из контекста перечисления
* Не проводит обращений к серверу.
*/
_CLOUD_DECL DWORD DssCertificateEnumNext(
    TDssCertificatesEnumContext enumContext, // полученный ранее контекст перечисления сертификатов
    TDssCertificateInfo* containerInfo       // выходной параметр со свойствами одного сертификата
);

/*
* Закрыть контекст перечисления
*/
_CLOUD_DECL void DssCertificatesEnumClose(
    TDssCertificatesEnumContext enumContext
);

/*
* Сформировать имя контейнера в формате DSS-xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.
*/
_CLOUD_DECL DWORD FormContainerName(
    const TDssServerInfo* serverInfo, // настройки сервера
    unsigned certificateId, // идентификатор сертификата на DSS
    char *szContName, // имя контейнера, по которому будет происходить адресация к контейнеру;
    size_t *contNameSize // длина буфера для получения имени контейнера
);

/*
* Обращение к серверу для сброса аутентификации
*/
_CLOUD_DECL DWORD DssDropAuthCookies(
    const TDssServerInfo* serverInfo // настройки сервера для сброса
);

/*
* Установка настроек таймаута подключения
*/
_CLOUD_DECL DWORD DssSetConnectionTimeout(
    unsigned short timeout //таймаут подключения
);

/*
* Запрос настроек таймаута подключения
*/
_CLOUD_DECL DWORD DssGetConnectionTimeout(
    unsigned short *timeout //таймаут подключения
);

/*
* Открытие перечисления зарегистрированных серверов.
*/
_CLOUD_DECL DWORD CloudServerSettingsEnumOpen(
    TCloudServerEnumCtx* enum_ctx // контекст перечисления
);

/*
* Открытие перечисления серверов, полученных через DiscoveryService.
*/
_CLOUD_DECL DWORD CloudServerSettingsEnumOpenFromDiscovery(
    const char* szDiscoveryURL, // адрес DiscoveryService (cервер, публикующий допустимые для использования DSS), м.б. NULL
    TCloudServerEnumCtx* enum_ctx // контекст перечисления
);

/*
* Получение базовых настроек одного сервера из перечисления.
*/
_CLOUD_DECL DWORD CloudServerSettingsEnumNext(
    TCloudServerEnumCtx enum_ctx, // контекст перечисления
    TDssServerInfo* serverInfo // выходной параметр с настройками одного сервера - указатели живут до CloudServerSettingsEnumClose
);

/*
* Получение расширенных настроек одного сервера из перечисления.
*/
_CLOUD_DECL DWORD ExtendedCloudServerSettingsEnumNext(
    TCloudServerEnumCtx enum_ctx, // контекст перечисления
    unsigned serverInfoVersion, // версия структуры TDssServerInfo
    TDssServerInfo* serverInfo // выходной параметр с базовыми настройками одного сервера - указатели живут до CloudServerSettingsEnumClose
);


/*
* Закрытие перечисления зарегистрированных серверов. Инвалидирует все ранее возвращенные данные. 
*/
_CLOUD_DECL void CloudServerSettingsEnumClose(
    TCloudServerEnumCtx enum_ctx // контекст перечисления
);

/*
* Сохранение базовой информации о сервере.
* Допустимые варианты TDssServerInfo: {unique, auth, rest}, {unique, user, pass}, {unique, auth, rest, user, pass}
*/
_CLOUD_DECL DWORD SaveCloudServerSettings(
    const TDssServerInfo* serverInfo, // сохраняемые настройки сервера
    BOOL isGlobal // признак сохранения настроек в глобальных настройках (нужны права администратора)
);

/*
* Сохранение расширенной информации о сервере.
* Допустимые варианты TDssServerInfo: {unique, auth, rest}, {unique, user, pass}, {unique, auth, rest, user, pass}
* Дополнительные поля (szDescription/bTestService) будут сохранены только при указанных {unique, auth, rest}
*/
_CLOUD_DECL DWORD SaveExtendedCloudServerSettings(
    const TDssServerInfo* serverInfo, // сохраняемые настройки сервера
    unsigned serverInfoVersion, // версия структуры TDssServerInfo
    BOOL isGlobal // признак сохранения настроек в глобальных настройках (нужны права администратора)
);

/*
* Удаление информации о сервере
*/
_CLOUD_DECL DWORD DeleteCloudServerSettings(
    const char *szUnique // уникальное имя сервера
);

/*
* Добавить отсутствующие регистрации серверов (в соответствии с установленными сертификатами)
*/
_CLOUD_DECL void UpdateCloudServerSettings();

/*
* Добавить отсутствующие регистрации серверов (в соответствии с данными DiscoveryService'а)
*/
_CLOUD_DECL void UpdateCloudServerSettingsUsingDiscovery(
    const char* szDiscoveryURL // адрес DiscoveryService (cервер, публикующий допустимые для использования DSS), м.б. NULL
);

/*
* Удалить сертификаты с некорретными ссылками на закрытый ключ
*/
_CLOUD_DECL DWORD UpdateCloudCertificates(
    const char *szUnique // уникальное имя сервера
);

#if defined( __cplusplus )
}
#endif /* defined( __cplusplus ) */

#endif // CLOUD_API_HEADER_H

