#ifndef _FS_SECURITY_C_H_
#define _FS_SECURITY_C_H_

#ifdef __cplusplus
extern "C" {
#endif


typedef struct _FSSecurityCallback FSSecurityCallback;

typedef struct _FSRMSSecurityCallback FSRMSSecurityCallback;

typedef struct _FSCustomSecurityCallback FSCustomSecurityCallback;

typedef struct _FSDRMSecurityCallback FSDRMSecurityCallback;

typedef struct _FSCertificateSecurityCallback FSCertificateSecurityCallback;


typedef enum _FSCipherType {
e_FSCipherNone = 0,
e_FSCipherRC4 = 1,
e_FSCipherAES = 2,
}FSCipherType;


FSErrorCode FSDK_SecurityHandler_Create(FS_SECURITYHANDLER_HANDLE* securityhandler_return_value);
FSErrorCode FSDK_SecurityHandler_Release(FS_SECURITYHANDLER_HANDLE securityhandler_handle);
FSErrorCode FSDK_SecurityHandler_IsEmpty(FS_SECURITYHANDLER_HANDLE securityhandler_handle, FS_BOOL* return_value);
FSErrorCode FSDK_SecurityHandler_GetSecurityType(FS_SECURITYHANDLER_HANDLE securityhandler_handle, FSEncryptType* return_value);
typedef struct _FSStdEncryptData {
  FS_BOOL is_encrypt_metadata;
  FS_UINT32 user_permissions;
  FSCipherType cipher;
  int key_length;
}FSStdEncryptData;


typedef enum _FSModifyFlag {
e_FSModifyPermission = 0x01,
e_FSModifyUserPassword = 0x02,
e_FSModifyOwnerPassword = 0x04,
}FSModifyFlag;


FSErrorCode FSDK_StdSecurityHandler_Create(FS_STDSECURITYHANDLER_HANDLE* stdsecurityhandler_return_value);
FSErrorCode FSDK_StdSecurityHandler_Create0(const FS_SECURITYHANDLER_HANDLE other, FS_STDSECURITYHANDLER_HANDLE* stdsecurityhandler_return_value);
FSErrorCode FSDK_StdSecurityHandler_Initialize(FS_STDSECURITYHANDLER_HANDLE stdsecurityhandler_handle, const FSStdEncryptData encrypt_data, const char* user_password, const char* owner_password, FS_BOOL* return_value);
FSErrorCode FSDK_StdSecurityHandler_InitializeW(FS_STDSECURITYHANDLER_HANDLE stdsecurityhandler_handle, const FSStdEncryptData encrypt_data, const wchar_t* user_password, const wchar_t* owner_password, FS_BOOL* return_value);
FSErrorCode FSDK_StdSecurityHandler_SetAES256ModifyFlags(FS_STDSECURITYHANDLER_HANDLE stdsecurityhandler_handle, FS_UINT32 modify_flags);
typedef struct _FSCertificateEncryptData {
  FS_BOOL is_encrypt_metadata;
  FSCipherType cipher;
  FS_BSTR* envelopes;
  FS_UINT32 envelopes_length;
}FSCertificateEncryptData;

FSErrorCode FSDK_CertificateSecurityHandler_Create(FS_CERTIFICATESECURITYHANDLER_HANDLE* certificatesecurityhandler_return_value);
FSErrorCode FSDK_CertificateSecurityHandler_Create0(const FS_SECURITYHANDLER_HANDLE other, FS_CERTIFICATESECURITYHANDLER_HANDLE* certificatesecurityhandler_return_value);
FSErrorCode FSDK_CertificateSecurityHandler_Initialize(FS_CERTIFICATESECURITYHANDLER_HANDLE certificatesecurityhandler_handle, const FSCertificateEncryptData encrypt_data, const char* encrypt_key, FS_BOOL* return_value);
typedef struct _FSDRMEncryptData {
  FS_BOOL is_encrypt_metadata;
  FS_BSTR sub_filter;
  FSCipherType cipher;
  int key_length;
  FS_BOOL is_owner;
  FS_UINT32 user_permissions;
}FSDRMEncryptData;

FSErrorCode FSDK_DRMSecurityHandler_Create(FS_DRMSECURITYHANDLER_HANDLE* drmsecurityhandler_return_value);
FSErrorCode FSDK_DRMSecurityHandler_Create0(const FS_SECURITYHANDLER_HANDLE other, FS_DRMSECURITYHANDLER_HANDLE* drmsecurityhandler_return_value);
FSErrorCode FSDK_DRMSecurityHandler_Initialize(FS_DRMSECURITYHANDLER_HANDLE drmsecurityhandler_handle, const FSDRMEncryptData encrypt_data, const char* file_id, const char* initial_key, FS_BOOL* return_value);
FSErrorCode FSDK_DRMSecurityHandler_GetDRMValue(FS_DRMSECURITYHANDLER_HANDLE drmsecurityhandler_handle, const char* key, FS_WSTR* return_value);
FSErrorCode FSDK_DRMSecurityHandler_SetDRMValue(FS_DRMSECURITYHANDLER_HANDLE drmsecurityhandler_handle, const char* key, const wchar_t* value, FS_BOOL* return_value);
FSErrorCode FSDK_DRMSecurityHandler_VerifyEncryptionParams(FS_DRMSECURITYHANDLER_HANDLE drmsecurityhandler_handle, FS_BOOL* return_value);
typedef struct _FSCustomEncryptData {
  FS_BOOL is_encrypt_metadata;
  FS_BSTR filter;
  FS_BSTR sub_filter;
}FSCustomEncryptData;

FSErrorCode FSDK_CustomSecurityHandler_Create(FS_CUSTOMSECURITYHANDLER_HANDLE* customsecurityhandler_return_value);
FSErrorCode FSDK_CustomSecurityHandler_Create0(const FS_SECURITYHANDLER_HANDLE other, FS_CUSTOMSECURITYHANDLER_HANDLE* customsecurityhandler_return_value);
FSErrorCode FSDK_CustomSecurityHandler_Initialize(FS_CUSTOMSECURITYHANDLER_HANDLE customsecurityhandler_handle, const FSCustomEncryptData encrypt_data,
                  const FSCustomSecurityCallback* callback, const char* encrypt_info, FS_BOOL* return_value);
typedef struct _FSRMSEncryptData {
  FS_BOOL is_encrypt_metadata;
  FS_BSTR publish_license;
  FS_BSTR* server_eul_list;
  FS_UINT32 server_eul_list_length;
  float irm_version;
}FSRMSEncryptData;

FSErrorCode FSDK_RMSSecurityHandler_Create(FS_RMSSECURITYHANDLER_HANDLE* rmssecurityhandler_return_value);
FSErrorCode FSDK_RMSSecurityHandler_Create0(const FS_SECURITYHANDLER_HANDLE other, FS_RMSSECURITYHANDLER_HANDLE* rmssecurityhandler_return_value);
FSErrorCode FSDK_RMSSecurityHandler_Initialize(FS_RMSSECURITYHANDLER_HANDLE rmssecurityhandler_handle, const FSRMSEncryptData encrypt_data, const FSRMSSecurityCallback* callback, FS_BOOL* return_value);
typedef struct _FSSecurityCallback {
  void* user_data;
  void (*Release)(void* user_data);
  FSEncryptType (*GetSecurityType)(void* user_data);
}FSSecurityCallback;

typedef struct _FSCertificateSecurityCallback {
  void* user_data;
  FSSecurityCallback *securitycallback;
  FSEncryptType (*GetSecurityType)(void* user_data);
  FS_BSTR (*GetDecryptionKey)(void* user_data, const void* envelope_buffer, FS_UINT32 envelope_length);
}FSCertificateSecurityCallback;

typedef struct _FSDRMSecurityCallback {
  void* user_data;
  FSSecurityCallback *securitycallback;
  FSEncryptType (*GetSecurityType)(void* user_data);
  FS_BOOL (*IsOwner)(void* user_data, const FS_PDFDOC_HANDLE document, const char* sub_filter);
  FS_UINT32 (*GetUserPermissions)(void* user_data, const FS_PDFDOC_HANDLE document, const char* sub_filter);
  FSCipherType (*GetCipherType)(void* user_data, const FS_PDFDOC_HANDLE document, const char* sub_filter);
  FS_UINT32 (*GetKeyLength)(void* user_data, const FS_PDFDOC_HANDLE document, const char* sub_filter);
  FS_BSTR (*GetFileID)(void* user_data, const FS_PDFDOC_HANDLE document, const char* sub_filter);
  FS_BSTR (*GetInitialKey)(void* user_data, const FS_PDFDOC_HANDLE document, const char* sub_filter);
}FSDRMSecurityCallback;

typedef struct _FSCustomSecurityCallback {
  void* user_data;
  FSSecurityCallback *securitycallback;
  FSEncryptType (*GetSecurityType)(void* user_data);
  void* (*CreateContext)(void* user_data, const char* filter, const char* sub_filter, const char* encrypt_info);
  FS_BOOL (*ReleaseContext)(void* user_data, void* context);
  FS_UINT32 (*GetUserPermissions)(void* user_data, const void* context, FS_UINT32 user_permission);
  FS_BOOL (*IsOwner)(void* user_data, const void* context);
  FSCipherType (*GetCipher)(void* user_data, const void* context);
  FS_BSTR (*GetEncryptKey)(void* user_data, const void* context);
  FS_UINT32 (*GetDecryptedSize)(void* user_data, const void* context, FS_UINT32 src_data_size);
  void* (*StartDecryptor)(void* user_data, const void* context, int obj_num, int gen_num);
  FS_BSTR (*DecryptData)(void* user_data, const void* decryptor, const void* encrypted_data, FS_UINT32 encrypted_data_len);
  FS_BSTR (*FinishDecryptor)(void* user_data, void* decryptor);
  FS_UINT32 (*GetEncryptedSize)(void* user_data, const void* context, int obj_num, int gen_num,
                                  const void* src_data, FS_UINT32 src_data_len);
  FS_BOOL (*EncryptData)(void* user_data, const void* context, int obj_num, int gen_num,
                           const void* src_data, FS_UINT32 src_data_len,
                           void* out_dst_buffer, FS_UINT32* out_dst_buffer_len);
  FS_BOOL (*UseStandardCryptoMethod)(void* user_data, const void* context);
  
}FSCustomSecurityCallback;

typedef struct _FSRMSSecurityCallback {
  void* user_data;
  FSCustomSecurityCallback *customsecuritycallback;
  FSEncryptType (*GetSecurityType)(void* user_data);
  
}FSRMSSecurityCallback;

#ifdef __cplusplus
}
#endif
#endif
