#ifndef CPP_ENROLL_PRIVATEKEY_OBJECT_H_
#define CPP_ENROLL_PRIVATEKEY_OBJECT_H_

#include "cppcades.h"
#include "CPPEnrollObjectId.h"
#include "CPPEnrollEnumerations.h"
#include "CPPProtectedPin.h"
#include "CPPEnrollX509PublicKey.h"

using namespace ATL;

namespace CryptoPro {
namespace PKI {
namespace Enroll {

class CPPEnrollX509PrivateKey
{
public:
    CPPEnrollX509PrivateKey(void);
    ~CPPEnrollX509PrivateKey(void);

    HRESULT get_Algorithm(boost::shared_ptr<CPPEnrollObjectId>& pVal);
    HRESULT put_Algorithm(boost::shared_ptr<CPPEnrollObjectId> newVal);

    HRESULT get_ContainerName(CAtlString& pVal);
    HRESULT put_ContainerName(CAtlString newVal);

    HRESULT get_UniqueContainerName(CAtlString& pVal);

    HRESULT get_CspInformations(void **ppValue); //ICspInformations
    HRESULT put_CspInformations(void *pValue);

    HRESULT get_CspStatus(void **ppValue);//ICspStatus
    HRESULT put_CspStatus(void *ppValue);

    HRESULT get_Existing(bool* pVal);
    HRESULT put_Existing(bool newVal);

    HRESULT get_ExportPolicy(X509PrivateKeyExportFlags* pVal);
    HRESULT put_ExportPolicy(X509PrivateKeyExportFlags newVal);

    HRESULT get_KeyProtection(X509PrivateKeyProtection* pVal);
    HRESULT put_KeyProtection(X509PrivateKeyProtection newVal);

    HRESULT get_KeySpec(X509KeySpec *pVal);
    HRESULT put_KeySpec(const X509KeySpec newVal);

    HRESULT get_KeyUsage(X509PrivateKeyUsageFlags *pVal);
    HRESULT put_KeyUsage(X509PrivateKeyUsageFlags newVal);

    HRESULT get_LegacyCsp(bool* pVal);
    HRESULT put_LegacyCsp(bool newVal);

    HRESULT get_Length(DWORD* pVal);
    HRESULT put_Length(const DWORD newVal);

    HRESULT get_MachineContext(bool* pVal);
    HRESULT put_MachineContext(bool newVal);

    HRESULT get_ProviderName(CAtlString& pVal);
    HRESULT put_ProviderName(CAtlString newVal);

    HRESULT get_ProviderType(X509ProviderType *pVal);
    HRESULT put_ProviderType(X509ProviderType newVal);

    HRESULT put_Pin(CAtlStringA& pVal);
    HRESULT put_Silent(BOOL bVal);
    HRESULT put_ForceReaderDialog(BOOL bVal);

    // web-disabled
    HRESULT Create();
    HRESULT Open();
    HRESULT ExportPublicKey(boost::shared_ptr<CPPEnrollX509PublicKey>& pPublicKey);

    // internal
    HRESULT CreateOrOpen();
    HRESULT SignAndEncode(LPCSTR lpszStructType, const void *pvStructInfo,
        PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, CStringBlob& Result);
    const CRYPT_KEY_PROV_INFO* GetKeyProvInfo();
    HRESULT CreateContainerName();
    HRESULT GetUniqueContainerName();

private:
    DISALLOW_COPY_AND_ASSIGN(CPPEnrollX509PrivateKey);
    HRESULT CheckState();
    CAtlString m_containerName;
    CAtlString m_uniqueContainerName;
    BOOL m_containerNameSet;
    CAtlString m_providerName;
    X509ProviderType m_providerType;
    DWORD m_dwKeySpec;
    X509PrivateKeyUsageFlags m_keyUsageFlags;
    X509PrivateKeyExportFlags m_keyExportFlags;
    X509PrivateKeyProtection m_privateKeyProtection;
    bool m_bMachineContext;
    bool m_bExisting;
    bool m_bLegacyCsp;
    bool m_bSilent;
    bool m_bForceReaderDialog;
    DWORD m_dwLength;
    boost::shared_ptr<CPPEnrollObjectId> m_algorithm;
    CProtectedPin m_pin;
    CCryptProvEx m_hProv;
    boost::shared_ptr<CPPEnrollX509PublicKey> m_publicKey;
    CCryptKeyProvInfo m_KeyProvInfo;
};
} /* namespace Enroll */
} /* namespace PKI */
} /* namespace CryptoPro */

#endif // CPP_ENROLL_PRIVATEKEY_OBJECT_H_

