// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) TypeSpec Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

#pragma once

#include "key_vault_client_options.hpp"
#include "key_vault_client_paged_responses.hpp"
#include "keys_models.hpp"

#include <azure/core/context.hpp>
#include <azure/core/credentials/credentials.hpp>
#include <azure/core/datetime.hpp>
#include <azure/core/internal/extendable_enumeration.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <azure/core/nullable.hpp>
#include <azure/core/paged_response.hpp>
#include <azure/core/response.hpp>
#include <azure/core/url.hpp>

#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace Azure { namespace Security { namespace KeyVault { namespace Keys { namespace _detail {
  /**
   * @brief The key vault client performs cryptographic key operations and vault operations against
   * the Key Vault service.
   *
   */
  class KeyVaultClient final {
  public:
    /**
     * @brief Constructs the KeyVaultClient.
     * @param url The URL address where the client will send the requests to.
     * @param credential Credential to authenticate with the service.
     * @param options Optional parameters.
     *
     */
    explicit KeyVaultClient(
        const std::string& url,
        const std::shared_ptr<const Core::Credentials::TokenCredential>& credential,
        const KeyVaultClientOptions& options = {});

    /**
     * @brief Gets the KeyVaultClient URL endpoint.
     * @return The KeyVaultClient's URL endpoint.
     *
     */
    std::string GetUrl() const;

    /**
     * @brief The create key operation can be used to create any key type in Azure Key Vault. If the
     * named key already exists, Azure Key Vault creates a new version of the key. It requires the
     * keys/create permission.
     * @param keyName The name for the new key. The system will generate the version name for the
     * new key. The value you provide may be copied globally for the purpose of running the service.
     * The value provided should not include personally identifiable or sensitive information.
     * @param parameters The parameters to create a key.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> CreateKey(
        const std::string& keyName,
        const Models::KeyCreateParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The operation will rotate the key based on the key policy. It requires the keys/rotate
     * permission.
     * @param keyName The name of key to be rotated. The system will generate a new version in the
     * specified key.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> RotateKey(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief The import key operation may be used to import any key type into an Azure Key Vault.
     * If the named key already exists, Azure Key Vault creates a new version of the key. This
     * operation requires the keys/import permission.
     * @param keyName Name for the imported key. The value you provide may be copied globally for
     * the purpose of running the service. The value provided should not include personally
     * identifiable or sensitive information.
     * @param parameters The parameters to import a key.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> ImportKey(
        const std::string& keyName,
        const Models::KeyImportParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The delete key operation cannot be used to remove individual versions of a key. This
     * operation removes the cryptographic material associated with the key, which means the key is
     * not usable for Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation
     * requires the keys/delete permission.
     * @param keyName The name of the key to delete.
     * @param context The context for the operation can be used for request cancellation.
     * @return A DeletedKeyBundle consisting of a WebKey plus its Attributes and deletion info
     *
     */
    Response<Models::DeletedKeyBundle> DeleteKey(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief In order to perform this operation, the key must already exist in the Key Vault. Note:
     * The cryptographic material of a key itself cannot be changed. This operation requires the
     * keys/update permission.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @param parameters The parameters of the key to update.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> UpdateKey(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyUpdateParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The get key operation is applicable to all key types. If the requested key is
     * symmetric, then no key material is released in the response. This operation requires the
     * keys/get permission.
     * @param keyName The name of the key to get.
     * @param keyVersion Adding the version parameter retrieves a specific version of a key. This
     * URI fragment is optional. If not specified, the latest version of the key is returned.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> GetKey(
        const std::string& keyName,
        const std::string& keyVersion,
        const Core::Context& context = {}) const;

    /**
     * @brief The full key identifier, attributes, and tags are provided in the response. This
     * operation requires the keys/list permission.
     * @param keyName The name of the key.
     * @param options Optional parameters.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key list result.
     *
     */
    GetKeyVersionsPagedResponse GetKeyVersions(
        const std::string& keyName,
        const KeyVaultClientGetKeyVersionsOptions& options = {},
        const Core::Context& context = {}) const;

    /**
     * @brief Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain
     * the public part of a stored key. The LIST operation is applicable to all key types, however
     * only the base key identifier, attributes, and tags are provided in the response. Individual
     * versions of a key are not listed in the response. This operation requires the keys/list
     * permission.
     * @param options Optional parameters.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key list result.
     *
     */
    GetKeysPagedResponse GetKeys(
        const KeyVaultClientGetKeysOptions& options = {},
        const Core::Context& context = {}) const;

    /**
     * @brief The Key Backup operation exports a key from Azure Key Vault in a protected form. Note
     * that this operation does NOT return key material in a form that can be used outside the Azure
     * Key Vault system, the returned key material is either protected to a Azure Key Vault HSM or
     * to Azure Key Vault itself. The intent of this operation is to allow a client to GENERATE a
     * key in one Azure Key Vault instance, BACKUP the key, and then RESTORE it into another Azure
     * Key Vault instance. The BACKUP operation may be used to export, in protected form, any key
     * type from Azure Key Vault. Individual versions of a key cannot be backed up. BACKUP / RESTORE
     * can be performed within geographical boundaries only; meaning that a BACKUP from one
     * geographical area cannot be restored to another geographical area. For example, a backup from
     * the US geographical area cannot be restored in an EU geographical area. This operation
     * requires the key/backup permission.
     * @param keyName The name of the key.
     * @param context The context for the operation can be used for request cancellation.
     * @return The backup key result, containing the backup blob.
     *
     */
    Response<Models::BackupKeyResult> BackupKey(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief Imports a previously backed up key into Azure Key Vault, restoring the key, its key
     * identifier, attributes and access control policies. The RESTORE operation may be used to
     * import a previously backed up key. Individual versions of a key cannot be restored. The key
     * is restored in its entirety with the same key name as it had when it was backed up. If the
     * key name is not available in the target Key Vault, the RESTORE operation will be rejected.
     * While the key name is retained during restore, the final key identifier will change if the
     * key is restored to a different vault. Restore will restore all versions and preserve version
     * identifiers. The RESTORE operation is subject to security constraints: The target Key Vault
     * must be owned by the same Microsoft Azure Subscription as the source Key Vault The user must
     * have RESTORE permission in the target Key Vault. This operation requires the keys/restore
     * permission.
     * @param parameters The parameters to restore the key.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> RestoreKey(
        const Models::KeyRestoreParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key
     * that is stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single
     * block of data, the size of which is dependent on the target key and the encryption algorithm
     * to be used. The ENCRYPT operation is only strictly necessary for symmetric keys stored in
     * Azure Key Vault since protection with an asymmetric key can be performed using public portion
     * of the key. This operation is supported for asymmetric keys as a convenience for callers that
     * have a key-reference but do not have access to the public key material. This operation
     * requires the keys/encrypt permission.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param parameters The parameters for the encryption operation.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key operation result.
     *
     */
    Response<Models::KeyOperationResult> Encrypt(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyOperationsParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The DECRYPT operation decrypts a well-formed block of ciphertext using the target
     * encryption key and specified algorithm. This operation is the reverse of the ENCRYPT
     * operation; only a single block of data may be decrypted, the size of this block is dependent
     * on the target key and the algorithm to be used. The DECRYPT operation applies to asymmetric
     * and symmetric keys stored in Azure Key Vault since it uses the private portion of the key.
     * This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC
     * algorithms for decryption without first ensuring the integrity of the ciphertext using an
     * HMAC, for example. See
     * https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more
     * information.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param parameters The parameters for the decryption operation.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key operation result.
     *
     */
    Response<Models::KeyOperationResult> Decrypt(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyOperationsParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key
     * Vault since this operation uses the private portion of the key. This operation requires the
     * keys/sign permission.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param parameters The parameters for the signing operation.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key operation result.
     *
     */
    Response<Models::KeyOperationResult> Sign(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeySignParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY
     * is not strictly necessary for asymmetric keys stored in Azure Key Vault since signature
     * verification can be performed using the public portion of the key but this operation is
     * supported as a convenience for callers that only have a key-reference and not the public
     * portion of the key. This operation requires the keys/verify permission.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param parameters The parameters for verify operations.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key verify result.
     *
     */
    Response<Models::KeyVerifyResult> Verify(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyVerifyParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The WRAP operation supports encryption of a symmetric key using a key encryption key
     * that has previously been stored in an Azure Key Vault. The WRAP operation is only strictly
     * necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric
     * key can be performed using the public portion of the key. This operation is supported for
     * asymmetric keys as a convenience for callers that have a key-reference but do not have access
     * to the public key material. This operation requires the keys/wrapKey permission.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param parameters The parameters for wrap operation.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key operation result.
     *
     */
    Response<Models::KeyOperationResult> WrapKey(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyOperationsParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The UNWRAP operation supports decryption of a symmetric key using the target key
     * encryption key. This operation is the reverse of the WRAP operation. The UNWRAP operation
     * applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private
     * portion of the key. This operation requires the keys/unwrapKey permission.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param parameters The parameters for the key operation.
     * @param context The context for the operation can be used for request cancellation.
     * @return The key operation result.
     *
     */
    Response<Models::KeyOperationResult> UnwrapKey(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyOperationsParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The release key operation is applicable to all key types. The target key must be
     * marked exportable. This operation requires the keys/release permission.
     * @param keyName The name of the key to get.
     * @param keyVersion Adding the version parameter retrieves a specific version of a key.
     * @param parameters The parameters for the key release operation.
     * @param context The context for the operation can be used for request cancellation.
     * @return The release result, containing the released key.
     *
     */
    Response<Models::KeyReleaseResult> Release(
        const std::string& keyName,
        const std::string& keyVersion,
        const Models::KeyReleaseParameters& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain
     * the public part of a deleted key. This operation includes deletion-specific information. The
     * Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the
     * operation can be invoked on any vault, it will return an error if invoked on a non
     * soft-delete enabled vault. This operation requires the keys/list permission.
     * @param options Optional parameters.
     * @param context The context for the operation can be used for request cancellation.
     * @return A list of keys that have been deleted in this vault.
     *
     */
    GetDeletedKeysPagedResponse GetDeletedKeys(
        const KeyVaultClientGetDeletedKeysOptions& options = {},
        const Core::Context& context = {}) const;

    /**
     * @brief The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the
     * operation can be invoked on any vault, it will return an error if invoked on a non
     * soft-delete enabled vault. This operation requires the keys/get permission.
     * @param keyName The name of the key.
     * @param context The context for the operation can be used for request cancellation.
     * @return A DeletedKeyBundle consisting of a WebKey plus its Attributes and deletion info
     *
     */
    Response<Models::DeletedKeyBundle> GetDeletedKey(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While
     * the operation can be invoked on any vault, it will return an error if invoked on a non
     * soft-delete enabled vault. This operation requires the keys/purge permission.
     * @param keyName The name of the key
     * @param context The context for the operation can be used for request cancellation.
     * @return Operation result.
     *
     */
    Response<Models::PurgeDeletedKeyResult> PurgeDeletedKey(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief The Recover Deleted Key operation is applicable for deleted keys in soft-delete
     * enabled vaults. It recovers the deleted key back to its latest version under /keys. An
     * attempt to recover an non-deleted key will return an error. Consider this the inverse of the
     * delete operation on soft-delete enabled vaults. This operation requires the keys/recover
     * permission.
     * @param keyName The name of the deleted key.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> RecoverDeletedKey(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief The GetKeyRotationPolicy operation returns the specified key policy resources in the
     * specified key vault. This operation requires the keys/get permission.
     * @param keyName The name of the key in a given key vault.
     * @param context The context for the operation can be used for request cancellation.
     * @return Management policy for a key.
     *
     */
    Response<Models::KeyRotationPolicy> GetKeyRotationPolicy(
        const std::string& keyName,
        const Core::Context& context = {}) const;

    /**
     * @brief Set specified members in the key policy. Leave others as undefined. This operation
     * requires the keys/update permission.
     * @param keyName The name of the key in the given vault.
     * @param keyRotationPolicy The policy for the key.
     * @param context The context for the operation can be used for request cancellation.
     * @return Management policy for a key.
     *
     */
    Response<Models::KeyRotationPolicy> UpdateKeyRotationPolicy(
        const std::string& keyName,
        const Models::KeyRotationPolicy& keyRotationPolicy,
        const Core::Context& context = {}) const;

    /**
     * @brief Get the requested number of bytes containing random values from a managed HSM.
     * @param parameters The request object to get random bytes.
     * @param context The context for the operation can be used for request cancellation.
     * @return The get random bytes response object containing the bytes.
     *
     */
    Response<Models::RandomBytes> GetRandomBytes(
        const Models::GetRandomBytesRequest& parameters,
        const Core::Context& context = {}) const;

    /**
     * @brief The get key attestation operation returns the key along with its attestation blob.
     * This operation requires the keys/get permission.
     * @param keyName The name of the key to retrieve attestation for.
     * @param keyVersion Adding the version parameter retrieves attestation blob for specific
     * version of a key. This URI fragment is optional. If not specified, the latest version of the
     * key attestation blob is returned.
     * @param context The context for the operation can be used for request cancellation.
     * @return A KeyBundle consisting of a WebKey plus its attributes.
     *
     */
    Response<Models::KeyBundle> GetKeyAttestation(
        const std::string& keyName,
        const std::string& keyVersion,
        const Core::Context& context = {}) const;

  private:
    std::shared_ptr<Core::Http::_internal::HttpPipeline> m_pipeline;
    Core::Url m_url;
    std::string m_apiVersion;
  };
}}}}} // namespace Azure::Security::KeyVault::Keys::_detail
