text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: secrets_manager
using AWS.Compat
using AWS.UUIDs

"""
    cancel_rotate_secret(secret_id)
    cancel_rotate_secret(secret_id, params::Dict{String,<:Any})

Disables automatic scheduled rotation and cancels the rotation of a secret if currently in
progress. To re-enable scheduled rotation, call RotateSecret with
AutomaticallyRotateAfterDays set to a value greater than 0. This immediately rotates your
secret and then enables the automatic schedule.  If you cancel a rotation while in
progress, it can leave the VersionStage labels in an unexpected state. Depending on the
step of the rotation in progress, you might need to remove the staging label AWSPENDING
from the partially created version, specified by the VersionId response value. You should
also evaluate the partially rotated new version to see if it should be deleted, which you
can do by removing all staging labels from the new version VersionStage field.  To
successfully start a rotation, the staging label AWSPENDING must be in one of the following
states:   Not attached to any version at all   Attached to the same version as the staging
label AWSCURRENT    If the staging label AWSPENDING attached to a different version than
the version with AWSCURRENT then the attempt to rotate fails.  Minimum permissions  To run
this command, you must have the following permissions:   secretsmanager:CancelRotateSecret
  Related operations    To configure rotation for a secret or to manually trigger a
rotation, use RotateSecret.   To get the rotation configuration details for a secret, use
DescribeSecret.   To list all of the currently available secrets, use ListSecrets.   To
list all of the versions currently associated with a secret, use ListSecretVersionIds.

# Arguments
- `secret_id`: Specifies the secret to cancel a rotation request. You can specify either
  the Amazon Resource Name (ARN) or the friendly name of the secret. For an ARN, we recommend
  that you specify a complete ARN rather than a partial ARN.

"""
function cancel_rotate_secret(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "CancelRotateSecret",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function cancel_rotate_secret(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "CancelRotateSecret",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_secret(name)
    create_secret(name, params::Dict{String,<:Any})

Creates a new secret. A secret in Secrets Manager consists of both the protected secret
data and the important information needed to manage the secret. Secrets Manager stores the
encrypted secret data in one of a collection of \"versions\" associated with the secret.
Each version contains a copy of the encrypted secret data. Each version is associated with
one or more \"staging labels\" that identify where the version is in the rotation cycle.
The SecretVersionsToStages field of the secret contains the mapping of staging labels to
the active versions of the secret. Versions without a staging label are considered
deprecated and not included in the list. You provide the secret data to be encrypted by
putting text in either the SecretString parameter or binary data in the SecretBinary
parameter, but not both. If you include SecretString or SecretBinary then Secrets Manager
also creates an initial secret version and automatically attaches the staging label
AWSCURRENT to the new version.    If you call an operation to encrypt or decrypt the
SecretString or SecretBinary for a secret in the same account as the calling user and that
secret doesn't specify a Amazon Web Services KMS encryption key, Secrets Manager uses the
account's default Amazon Web Services managed customer master key (CMK) with the alias
aws/secretsmanager. If this key doesn't already exist in your account then Secrets Manager
creates it for you automatically. All users and roles in the same Amazon Web Services
account automatically have access to use the default CMK. Note that if an Secrets Manager
API call results in Amazon Web Services creating the account's Amazon Web Services-managed
CMK, it can result in a one-time significant delay in returning the result.   If the secret
resides in a different Amazon Web Services account from the credentials calling an API that
requires encryption or decryption of the secret value then you must create and use a custom
Amazon Web Services KMS CMK because you can't access the default CMK for the account using
credentials from a different Amazon Web Services account. Store the ARN of the CMK in the
secret when you create the secret or when you update it by including it in the KMSKeyId. If
you call an API that must encrypt or decrypt SecretString or SecretBinary using credentials
from a different account then the Amazon Web Services KMS key policy must grant
cross-account access to that other account's user or role for both the kms:GenerateDataKey
and kms:Decrypt operations.       Minimum permissions  To run this command, you must have
the following permissions:   secretsmanager:CreateSecret   kms:GenerateDataKey - needed
only if you use a customer-managed Amazon Web Services KMS key to encrypt the secret. You
do not need this permission to use the account default Amazon Web Services managed CMK for
Secrets Manager.   kms:Decrypt - needed only if you use a customer-managed Amazon Web
Services KMS key to encrypt the secret. You do not need this permission to use the account
default Amazon Web Services managed CMK for Secrets Manager.   secretsmanager:TagResource -
needed only if you include the Tags parameter.     Related operations    To delete a
secret, use DeleteSecret.   To modify an existing secret, use UpdateSecret.   To create a
new version of a secret, use PutSecretValue.   To retrieve the encrypted secure string and
secure binary values, use GetSecretValue.   To retrieve all other details for a secret, use
DescribeSecret. This does not include the encrypted secure string and secure binary values.
  To retrieve the list of secret versions associated with the current secret, use
DescribeSecret and examine the SecretVersionsToStages response value.

# Arguments
- `name`: Specifies the friendly name of the new secret. The secret name must be ASCII
  letters, digits, or the following characters : /_+=.@-  Do not end your secret name with a
  hyphen followed by six characters. If you do so, you risk confusion and unexpected results
  when searching for a secret by partial ARN. Secrets Manager automatically adds a hyphen and
  six random characters at the end of the ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"AddReplicaRegions"`: (Optional) Add a list of regions to replicate secrets. Secrets
  Manager replicates the KMSKeyID objects to the list of regions specified in the parameter.
- `"ClientRequestToken"`: (Optional) If you include SecretString or SecretBinary, then an
  initial version is created as part of the secret, and this parameter specifies a unique
  identifier for the new version.   If you use the Amazon Web Services CLI or one of the
  Amazon Web Services SDK to call this operation, then you can leave this parameter empty.
  The CLI or SDK generates a random UUID for you and includes it as the value for this
  parameter in the request. If you don't use the SDK and instead generate a raw HTTP request
  to the Secrets Manager service endpoint, then you must generate a ClientRequestToken
  yourself for the new version and include the value in the request.  This value helps ensure
  idempotency. Secrets Manager uses this value to prevent the accidental creation of
  duplicate versions if there are failures and retries during a rotation. We recommend that
  you generate a UUID-type value to ensure uniqueness of your versions within the specified
  secret.    If the ClientRequestToken value isn't already associated with a version of the
  secret then a new version of the secret is created.    If a version with this value already
  exists and the version SecretString and SecretBinary values are the same as those in the
  request, then the request is ignored.   If a version with this value already exists and
  that version's SecretString and SecretBinary values are different from those in the
  request, then the request fails because you cannot modify an existing version. Instead, use
  PutSecretValue to create a new version.   This value becomes the VersionId of the new
  version.
- `"Description"`: (Optional) Specifies a user-provided description of the secret.
- `"ForceOverwriteReplicaSecret"`: (Optional) If set, the replication overwrites a secret
  with the same name in the destination region.
- `"KmsKeyId"`: (Optional) Specifies the ARN, Key ID, or alias of the Amazon Web Services
  KMS customer master key (CMK) to be used to encrypt the SecretString or SecretBinary values
  in the versions stored in this secret. You can specify any of the supported ways to
  identify a Amazon Web Services KMS key ID. If you need to reference a CMK in a different
  account, you can use only the key ARN or the alias ARN. If you don't specify this value,
  then Secrets Manager defaults to using the Amazon Web Services account's default CMK (the
  one named aws/secretsmanager). If a Amazon Web Services KMS CMK with that name doesn't yet
  exist, then Secrets Manager creates it for you automatically the first time it needs to
  encrypt a version's SecretString or SecretBinary fields.  You can use the account default
  CMK to encrypt and decrypt only if you call this operation using credentials from the same
  account that owns the secret. If the secret resides in a different account, then you must
  create a custom CMK and specify the ARN in this field.
- `"SecretBinary"`: (Optional) Specifies binary data that you want to encrypt and store in
  the new version of the secret. To use this parameter in the command-line tools, we
  recommend that you store your binary data in a file and then use the appropriate technique
  for your tool to pass the contents of the file as a parameter. Either SecretString or
  SecretBinary must have a value, but not both. They cannot both be empty. This parameter is
  not available using the Secrets Manager console. It can be accessed only by using the
  Amazon Web Services CLI or one of the Amazon Web Services SDKs.
- `"SecretString"`: (Optional) Specifies text data that you want to encrypt and store in
  this new version of the secret. Either SecretString or SecretBinary must have a value, but
  not both. They cannot both be empty. If you create a secret by using the Secrets Manager
  console then Secrets Manager puts the protected secret text in only the SecretString
  parameter. The Secrets Manager console stores the information as a JSON structure of
  key/value pairs that the Lambda rotation function knows how to parse. For storing multiple
  values, we recommend that you use a JSON text string argument and specify key/value pairs.
  For more information, see Specifying parameter values for the Amazon Web Services CLI in
  the Amazon Web Services CLI User Guide.
- `"Tags"`: (Optional) Specifies a list of user-defined tags that are attached to the
  secret. Each tag is a \"Key\" and \"Value\" pair of strings. This operation only appends
  tags to the existing list of tags. To remove tags, you must use UntagResource.    Secrets
  Manager tag key names are case sensitive. A tag with the key \"ABC\" is a different tag
  from one with key \"abc\".   If you check tags in IAM policy Condition elements as part of
  your security strategy, then adding or removing a tag can change permissions. If the
  successful completion of this operation would result in you losing your permissions for
  this secret, then this operation is blocked and returns an Access Denied error.    This
  parameter requires a JSON text string argument. For information on how to format a JSON
  parameter for the various command line tool environments, see Using JSON for Parameters in
  the CLI User Guide. For example:
  [{\"Key\":\"CostCenter\",\"Value\":\"12345\"},{\"Key\":\"environment\",\"Value\":\"productio
  n\"}]  If your command-line tool or SDK requires quotation marks around the parameter, you
  should use single quotes to avoid confusion with the double quotes required in the JSON
  text.  The following basic restrictions apply to tags:   Maximum number of tags per
  secret—50   Maximum key length—127 Unicode characters in UTF-8   Maximum value
  length—255 Unicode characters in UTF-8   Tag keys and values are case sensitive.   Do not
  use the aws: prefix in your tag names or values because Amazon Web Services reserves it for
  Amazon Web Services use. You can't edit or delete tag names or values with this prefix.
  Tags with this prefix do not count against your tags per secret limit.   If you use your
  tagging schema across multiple services and resources, remember other services might have
  restrictions on allowed characters. Generally allowed characters: letters, spaces, and
  numbers representable in UTF-8, plus the following special characters: + - = . _ : / @.
"""
function create_secret(Name; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "CreateSecret",
        Dict{String,Any}("Name" => Name, "ClientRequestToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_secret(
    Name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "CreateSecret",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("Name" => Name, "ClientRequestToken" => string(uuid4())),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_resource_policy(secret_id)
    delete_resource_policy(secret_id, params::Dict{String,<:Any})

Deletes the resource-based permission policy attached to the secret.  Minimum permissions
To run this command, you must have the following permissions:
secretsmanager:DeleteResourcePolicy    Related operations    To attach a resource policy to
a secret, use PutResourcePolicy.   To retrieve the current resource-based policy attached
to a secret, use GetResourcePolicy.   To list all of the currently available secrets, use
ListSecrets.

# Arguments
- `secret_id`: Specifies the secret that you want to delete the attached resource-based
  policy for. You can specify either the Amazon Resource Name (ARN) or the friendly name of
  the secret. For an ARN, we recommend that you specify a complete ARN rather than a partial
  ARN.

"""
function delete_resource_policy(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "DeleteResourcePolicy",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_resource_policy(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "DeleteResourcePolicy",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_secret(secret_id)
    delete_secret(secret_id, params::Dict{String,<:Any})

Deletes an entire secret and all of the versions. You can optionally include a recovery
window during which you can restore the secret. If you don't specify a recovery window
value, the operation defaults to 30 days. Secrets Manager attaches a DeletionDate stamp to
the secret that specifies the end of the recovery window. At the end of the recovery
window, Secrets Manager deletes the secret permanently. At any time before recovery window
ends, you can use RestoreSecret to remove the DeletionDate and cancel the deletion of the
secret. You cannot access the encrypted secret information in any secret scheduled for
deletion. If you need to access that information, you must cancel the deletion with
RestoreSecret and then retrieve the information.    There is no explicit operation to
delete a version of a secret. Instead, remove all staging labels from the VersionStage
field of a version. That marks the version as deprecated and allows Secrets Manager to
delete it as needed. Versions without any staging labels do not show up in
ListSecretVersionIds unless you specify IncludeDeprecated.   The permanent secret deletion
at the end of the waiting period is performed as a background task with low priority. There
is no guarantee of a specific time after the recovery window for the actual delete
operation to occur.     Minimum permissions  To run this command, you must have the
following permissions:   secretsmanager:DeleteSecret    Related operations    To create a
secret, use CreateSecret.   To cancel deletion of a version of a secret before the recovery
window has expired, use RestoreSecret.

# Arguments
- `secret_id`: Specifies the secret to delete. You can specify either the Amazon Resource
  Name (ARN) or the friendly name of the secret. For an ARN, we recommend that you specify a
  complete ARN rather than a partial ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ForceDeleteWithoutRecovery"`: (Optional) Specifies that the secret is to be deleted
  without any recovery window. You can't use both this parameter and the RecoveryWindowInDays
  parameter in the same API call. An asynchronous background process performs the actual
  deletion, so there can be a short delay before the operation completes. If you write code
  to delete and then immediately recreate a secret with the same name, ensure that your code
  includes appropriate back off and retry logic.  Use this parameter with caution. This
  parameter causes the operation to skip the normal waiting period before the permanent
  deletion that Amazon Web Services would normally impose with the RecoveryWindowInDays
  parameter. If you delete a secret with the ForceDeleteWithouRecovery parameter, then you
  have no opportunity to recover the secret. You lose the secret permanently.   If you use
  this parameter and include a previously deleted or nonexistent secret, the operation does
  not return the error ResourceNotFoundException in order to correctly handle retries.
- `"RecoveryWindowInDays"`: (Optional) Specifies the number of days that Secrets Manager
  waits before Secrets Manager can delete the secret. You can't use both this parameter and
  the ForceDeleteWithoutRecovery parameter in the same API call. This value can range from 7
  to 30 days with a default value of 30.
"""
function delete_secret(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "DeleteSecret",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_secret(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "DeleteSecret",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_secret(secret_id)
    describe_secret(secret_id, params::Dict{String,<:Any})

Retrieves the details of a secret. It does not include the encrypted fields. Secrets
Manager only returns fields populated with a value in the response.   Minimum permissions
To run this command, you must have the following permissions:
secretsmanager:DescribeSecret    Related operations    To create a secret, use
CreateSecret.   To modify a secret, use UpdateSecret.   To retrieve the encrypted secret
information in a version of the secret, use GetSecretValue.   To list all of the secrets in
the Amazon Web Services account, use ListSecrets.

# Arguments
- `secret_id`: The identifier of the secret whose details you want to retrieve. You can
  specify either the Amazon Resource Name (ARN) or the friendly name of the secret. For an
  ARN, we recommend that you specify a complete ARN rather than a partial ARN.

"""
function describe_secret(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "DescribeSecret",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_secret(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "DescribeSecret",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_random_password()
    get_random_password(params::Dict{String,<:Any})

Generates a random password of the specified complexity. This operation is intended for use
in the Lambda rotation function. Per best practice, we recommend that you specify the
maximum length and include every character type that the system you are generating a
password for can support.  Minimum permissions  To run this command, you must have the
following permissions:   secretsmanager:GetRandomPassword

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ExcludeCharacters"`: A string that includes characters that should not be included in
  the generated password. The default is that all characters from the included sets can be
  used.
- `"ExcludeLowercase"`: Specifies that the generated password should not include lowercase
  letters. The default if you do not include this switch parameter is that lowercase letters
  can be included.
- `"ExcludeNumbers"`: Specifies that the generated password should not include digits. The
  default if you do not include this switch parameter is that digits can be included.
- `"ExcludePunctuation"`: Specifies that the generated password should not include
  punctuation characters. The default if you do not include this switch parameter is that
  punctuation characters can be included. The following are the punctuation characters that
  can be included in the generated password if you don't explicitly exclude them with
  ExcludeCharacters or ExcludePunctuation:  ! \" #  % & ' ( ) * + , - . / : ; < = >
  ? @ [  ] ^ _ ` { | } ~
- `"ExcludeUppercase"`: Specifies that the generated password should not include uppercase
  letters. The default if you do not include this switch parameter is that uppercase letters
  can be included.
- `"IncludeSpace"`: Specifies that the generated password can include the space character.
  The default if you do not include this switch parameter is that the space character is not
  included.
- `"PasswordLength"`: The desired length of the generated password. The default value if
  you do not include this parameter is 32 characters.
- `"RequireEachIncludedType"`: A boolean value that specifies whether the generated
  password must include at least one of every allowed character type. The default value is
  True and the operation requires at least one of every character type.
"""
function get_random_password(; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "GetRandomPassword"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function get_random_password(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "GetRandomPassword", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

"""
    get_resource_policy(secret_id)
    get_resource_policy(secret_id, params::Dict{String,<:Any})

Retrieves the JSON text of the resource-based policy document attached to the specified
secret. The JSON request string input and response output displays formatted code with
white space and line breaks for better readability. Submit your input as a single line JSON
string.  Minimum permissions  To run this command, you must have the following permissions:
  secretsmanager:GetResourcePolicy    Related operations    To attach a resource policy to
a secret, use PutResourcePolicy.   To delete the resource-based policy attached to a
secret, use DeleteResourcePolicy.   To list all of the currently available secrets, use
ListSecrets.

# Arguments
- `secret_id`: Specifies the secret that you want to retrieve the attached resource-based
  policy for. You can specify either the Amazon Resource Name (ARN) or the friendly name of
  the secret. For an ARN, we recommend that you specify a complete ARN rather than a partial
  ARN.

"""
function get_resource_policy(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "GetResourcePolicy",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_resource_policy(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "GetResourcePolicy",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_secret_value(secret_id)
    get_secret_value(secret_id, params::Dict{String,<:Any})

Retrieves the contents of the encrypted fields SecretString or SecretBinary from the
specified version of a secret, whichever contains content.  Minimum permissions  To run
this command, you must have the following permissions:   secretsmanager:GetSecretValue
kms:Decrypt - required only if you use a customer-managed Amazon Web Services KMS key to
encrypt the secret. You do not need this permission to use the account's default Amazon Web
Services managed CMK for Secrets Manager.    Related operations    To create a new version
of the secret with different encrypted information, use PutSecretValue.   To retrieve the
non-encrypted details for the secret, use DescribeSecret.

# Arguments
- `secret_id`: Specifies the secret containing the version that you want to retrieve. You
  can specify either the Amazon Resource Name (ARN) or the friendly name of the secret. For
  an ARN, we recommend that you specify a complete ARN rather than a partial ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"VersionId"`: Specifies the unique identifier of the version of the secret that you want
  to retrieve. If you specify both this parameter and VersionStage, the two parameters must
  refer to the same secret version. If you don't specify either a VersionStage or VersionId
  then the default is to perform the operation on the version with the VersionStage value of
  AWSCURRENT. This value is typically a UUID-type value with 32 hexadecimal digits.
- `"VersionStage"`: Specifies the secret version that you want to retrieve by the staging
  label attached to the version. Staging labels are used to keep track of different versions
  during the rotation process. If you specify both this parameter and VersionId, the two
  parameters must refer to the same secret version . If you don't specify either a
  VersionStage or VersionId, then the default is to perform the operation on the version with
  the VersionStage value of AWSCURRENT.
"""
function get_secret_value(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "GetSecretValue",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_secret_value(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "GetSecretValue",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_secret_version_ids(secret_id)
    list_secret_version_ids(secret_id, params::Dict{String,<:Any})

Lists all of the versions attached to the specified secret. The output does not include the
SecretString or SecretBinary fields. By default, the list includes only versions that have
at least one staging label in VersionStage attached.  Always check the NextToken response
parameter when calling any of the List* operations. These operations can occasionally
return an empty or shorter than expected list of results even when there more results
become available. When this happens, the NextToken response parameter contains a value to
pass to the next call to the same API to request the next part of the list.   Minimum
permissions  To run this command, you must have the following permissions:
secretsmanager:ListSecretVersionIds    Related operations    To list the secrets in an
account, use ListSecrets.

# Arguments
- `secret_id`: The identifier for the secret containing the versions you want to list. You
  can specify either the Amazon Resource Name (ARN) or the friendly name of the secret. For
  an ARN, we recommend that you specify a complete ARN rather than a partial ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"IncludeDeprecated"`: (Optional) Specifies that you want the results to include versions
  that do not have any staging labels attached to them. Such versions are considered
  deprecated and are subject to deletion by Secrets Manager as needed.
- `"MaxResults"`: (Optional) Limits the number of results you want to include in the
  response. If you don't include this parameter, it defaults to a value that's specific to
  the operation. If additional items exist beyond the maximum you specify, the NextToken
  response element is present and has a value (isn't null). Include that value as the
  NextToken request parameter in the next call to the operation to get the next part of the
  results. Note that Secrets Manager might return fewer results than the maximum even when
  there are more results available. You should check NextToken after every operation to
  ensure that you receive all of the results.
- `"NextToken"`: (Optional) Use this parameter in a request if you receive a NextToken
  response in a previous request indicating there's more output available. In a subsequent
  call, set it to the value of the previous call NextToken response to indicate where the
  output should continue from.
"""
function list_secret_version_ids(
    SecretId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "ListSecretVersionIds",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_secret_version_ids(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "ListSecretVersionIds",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_secrets()
    list_secrets(params::Dict{String,<:Any})

Lists all of the secrets that are stored by Secrets Manager in the Amazon Web Services
account. To list the versions currently stored for a specific secret, use
ListSecretVersionIds. The encrypted fields SecretString and SecretBinary are not included
in the output. To get that information, call the GetSecretValue operation.  Always check
the NextToken response parameter when calling any of the List* operations. These operations
can occasionally return an empty or shorter than expected list of results even when there
more results become available. When this happens, the NextToken response parameter contains
a value to pass to the next call to the same API to request the next part of the list.
Minimum permissions  To run this command, you must have the following permissions:
secretsmanager:ListSecrets    Related operations    To list the versions attached to a
secret, use ListSecretVersionIds.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"Filters"`: Lists the secret request filters.
- `"MaxResults"`: (Optional) Limits the number of results you want to include in the
  response. If you don't include this parameter, it defaults to a value that's specific to
  the operation. If additional items exist beyond the maximum you specify, the NextToken
  response element is present and has a value (isn't null). Include that value as the
  NextToken request parameter in the next call to the operation to get the next part of the
  results. Note that Secrets Manager might return fewer results than the maximum even when
  there are more results available. You should check NextToken after every operation to
  ensure that you receive all of the results.
- `"NextToken"`: (Optional) Use this parameter in a request if you receive a NextToken
  response in a previous request indicating there's more output available. In a subsequent
  call, set it to the value of the previous call NextToken response to indicate where the
  output should continue from.
- `"SortOrder"`: Lists secrets in the requested order.
"""
function list_secrets(; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "ListSecrets"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_secrets(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "ListSecrets", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

"""
    put_resource_policy(resource_policy, secret_id)
    put_resource_policy(resource_policy, secret_id, params::Dict{String,<:Any})

Attaches the contents of the specified resource-based permission policy to a secret. A
resource-based policy is optional. Alternatively, you can use IAM identity-based policies
that specify the secret's Amazon Resource Name (ARN) in the policy statement's Resources
element. You can also use a combination of both identity-based and resource-based policies.
The affected users and roles receive the permissions that are permitted by all of the
relevant policies. For more information, see Using Resource-Based Policies for Amazon Web
Services Secrets Manager. For the complete description of the Amazon Web Services policy
syntax and grammar, see IAM JSON Policy Reference in the IAM User Guide.  Minimum
permissions  To run this command, you must have the following permissions:
secretsmanager:PutResourcePolicy    Related operations    To retrieve the resource policy
attached to a secret, use GetResourcePolicy.   To delete the resource-based policy attached
to a secret, use DeleteResourcePolicy.   To list all of the currently available secrets,
use ListSecrets.

# Arguments
- `resource_policy`: A JSON-formatted string constructed according to the grammar and
  syntax for an Amazon Web Services resource-based policy. The policy in the string
  identifies who can access or manage this secret and its versions. For information on how to
  format a JSON parameter for the various command line tool environments, see Using JSON for
  Parameters in the CLI User Guide.
- `secret_id`: Specifies the secret that you want to attach the resource-based policy. You
  can specify either the ARN or the friendly name of the secret. For an ARN, we recommend
  that you specify a complete ARN rather than a partial ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"BlockPublicPolicy"`: (Optional) If you set the parameter, BlockPublicPolicy to true,
  then you block resource-based policies that allow broad access to the secret.
"""
function put_resource_policy(
    ResourcePolicy, SecretId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "PutResourcePolicy",
        Dict{String,Any}("ResourcePolicy" => ResourcePolicy, "SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function put_resource_policy(
    ResourcePolicy,
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "PutResourcePolicy",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "ResourcePolicy" => ResourcePolicy, "SecretId" => SecretId
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    put_secret_value(secret_id)
    put_secret_value(secret_id, params::Dict{String,<:Any})

Stores a new encrypted secret value in the specified secret. To do this, the operation
creates a new version and attaches it to the secret. The version can contain a new
SecretString value or a new SecretBinary value. You can also specify the staging labels
that are initially attached to the new version. We recommend you avoid calling
PutSecretValue at a sustained rate of more than once every 10 minutes. When you update the
secret value, Secrets Manager creates a new version of the secret. Secrets Manager removes
outdated versions when there are more than 100, but it does not remove versions created
less than 24 hours ago. If you call PutSecretValue more than once every 10 minutes, you
create more versions than Secrets Manager removes, and you will reach the quota for secret
versions.   If this operation creates the first version for the secret then Secrets Manager
automatically attaches the staging label AWSCURRENT to the new version.   If you do not
specify a value for VersionStages then Secrets Manager automatically moves the staging
label AWSCURRENT to this new version.   If this operation moves the staging label
AWSCURRENT from another version to this version, then Secrets Manager also automatically
moves the staging label AWSPREVIOUS to the version that AWSCURRENT was removed from.   This
operation is idempotent. If a version with a VersionId with the same value as the
ClientRequestToken parameter already exists and you specify the same secret data, the
operation succeeds but does nothing. However, if the secret data is different, then the
operation fails because you cannot modify an existing version; you can only create new
ones.      If you call an operation to encrypt or decrypt the SecretString or SecretBinary
for a secret in the same account as the calling user and that secret doesn't specify a
Amazon Web Services KMS encryption key, Secrets Manager uses the account's default Amazon
Web Services managed customer master key (CMK) with the alias aws/secretsmanager. If this
key doesn't already exist in your account then Secrets Manager creates it for you
automatically. All users and roles in the same Amazon Web Services account automatically
have access to use the default CMK. Note that if an Secrets Manager API call results in
Amazon Web Services creating the account's Amazon Web Services-managed CMK, it can result
in a one-time significant delay in returning the result.   If the secret resides in a
different Amazon Web Services account from the credentials calling an API that requires
encryption or decryption of the secret value then you must create and use a custom Amazon
Web Services KMS CMK because you can't access the default CMK for the account using
credentials from a different Amazon Web Services account. Store the ARN of the CMK in the
secret when you create the secret or when you update it by including it in the KMSKeyId. If
you call an API that must encrypt or decrypt SecretString or SecretBinary using credentials
from a different account then the Amazon Web Services KMS key policy must grant
cross-account access to that other account's user or role for both the kms:GenerateDataKey
and kms:Decrypt operations.     Minimum permissions  To run this command, you must have the
following permissions:   secretsmanager:PutSecretValue   kms:GenerateDataKey - needed only
if you use a customer-managed Amazon Web Services KMS key to encrypt the secret. You do not
need this permission to use the account's default Amazon Web Services managed CMK for
Secrets Manager.    Related operations    To retrieve the encrypted value you store in the
version of a secret, use GetSecretValue.   To create a secret, use CreateSecret.   To get
the details for a secret, use DescribeSecret.   To list the versions attached to a secret,
use ListSecretVersionIds.

# Arguments
- `secret_id`: Specifies the secret to which you want to add a new version. You can specify
  either the Amazon Resource Name (ARN) or the friendly name of the secret. The secret must
  already exist. For an ARN, we recommend that you specify a complete ARN rather than a
  partial ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientRequestToken"`: (Optional) Specifies a unique identifier for the new version of
  the secret.   If you use the Amazon Web Services CLI or one of the Amazon Web Services SDK
  to call this operation, then you can leave this parameter empty. The CLI or SDK generates a
  random UUID for you and includes that in the request. If you don't use the SDK and instead
  generate a raw HTTP request to the Secrets Manager service endpoint, then you must generate
  a ClientRequestToken yourself for new versions and include that value in the request.
  This value helps ensure idempotency. Secrets Manager uses this value to prevent the
  accidental creation of duplicate versions if there are failures and retries during the
  Lambda rotation function's processing. We recommend that you generate a UUID-type value to
  ensure uniqueness within the specified secret.    If the ClientRequestToken value isn't
  already associated with a version of the secret then a new version of the secret is
  created.    If a version with this value already exists and that version's SecretString or
  SecretBinary values are the same as those in the request then the request is ignored (the
  operation is idempotent).    If a version with this value already exists and the version of
  the SecretString and SecretBinary values are different from those in the request then the
  request fails because you cannot modify an existing secret version. You can only create new
  versions to store new secret values.   This value becomes the VersionId of the new version.
- `"SecretBinary"`: (Optional) Specifies binary data that you want to encrypt and store in
  the new version of the secret. To use this parameter in the command-line tools, we
  recommend that you store your binary data in a file and then use the appropriate technique
  for your tool to pass the contents of the file as a parameter. Either SecretBinary or
  SecretString must have a value, but not both. They cannot both be empty. This parameter is
  not accessible if the secret using the Secrets Manager console.
- `"SecretString"`: (Optional) Specifies text data that you want to encrypt and store in
  this new version of the secret. Either SecretString or SecretBinary must have a value, but
  not both. They cannot both be empty. If you create this secret by using the Secrets Manager
  console then Secrets Manager puts the protected secret text in only the SecretString
  parameter. The Secrets Manager console stores the information as a JSON structure of
  key/value pairs that the default Lambda rotation function knows how to parse. For storing
  multiple values, we recommend that you use a JSON text string argument and specify
  key/value pairs. For more information, see Specifying parameter values for the Amazon Web
  Services CLI in the Amazon Web Services CLI User Guide.
- `"VersionStages"`: (Optional) Specifies a list of staging labels that are attached to
  this version of the secret. These staging labels are used to track the versions through the
  rotation process by the Lambda rotation function. A staging label must be unique to a
  single version of the secret. If you specify a staging label that's already associated with
  a different version of the same secret then that staging label is automatically removed
  from the other version and attached to this version. If you do not specify a value for
  VersionStages then Secrets Manager automatically moves the staging label AWSCURRENT to this
  new version.
"""
function put_secret_value(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "PutSecretValue",
        Dict{String,Any}("SecretId" => SecretId, "ClientRequestToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function put_secret_value(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "PutSecretValue",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "SecretId" => SecretId, "ClientRequestToken" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    remove_regions_from_replication(remove_replica_regions, secret_id)
    remove_regions_from_replication(remove_replica_regions, secret_id, params::Dict{String,<:Any})

Remove regions from replication.

# Arguments
- `remove_replica_regions`: Remove replication from specific Regions.
- `secret_id`: Remove a secret by SecretId from replica Regions.

"""
function remove_regions_from_replication(
    RemoveReplicaRegions, SecretId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "RemoveRegionsFromReplication",
        Dict{String,Any}(
            "RemoveReplicaRegions" => RemoveReplicaRegions, "SecretId" => SecretId
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function remove_regions_from_replication(
    RemoveReplicaRegions,
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "RemoveRegionsFromReplication",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "RemoveReplicaRegions" => RemoveReplicaRegions, "SecretId" => SecretId
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    replicate_secret_to_regions(add_replica_regions, secret_id)
    replicate_secret_to_regions(add_replica_regions, secret_id, params::Dict{String,<:Any})

Converts an existing secret to a multi-Region secret and begins replication the secret to a
list of new regions.

# Arguments
- `add_replica_regions`: Add Regions to replicate the secret.
- `secret_id`: Use the Secret Id to replicate a secret to regions.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ForceOverwriteReplicaSecret"`: (Optional) If set, Secrets Manager replication
  overwrites a secret with the same name in the destination region.
"""
function replicate_secret_to_regions(
    AddReplicaRegions, SecretId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "ReplicateSecretToRegions",
        Dict{String,Any}("AddReplicaRegions" => AddReplicaRegions, "SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function replicate_secret_to_regions(
    AddReplicaRegions,
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "ReplicateSecretToRegions",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "AddReplicaRegions" => AddReplicaRegions, "SecretId" => SecretId
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    restore_secret(secret_id)
    restore_secret(secret_id, params::Dict{String,<:Any})

Cancels the scheduled deletion of a secret by removing the DeletedDate time stamp. This
makes the secret accessible to query once again.  Minimum permissions  To run this command,
you must have the following permissions:   secretsmanager:RestoreSecret    Related
operations    To delete a secret, use DeleteSecret.

# Arguments
- `secret_id`: Specifies the secret that you want to restore from a previously scheduled
  deletion. You can specify either the Amazon Resource Name (ARN) or the friendly name of the
  secret. For an ARN, we recommend that you specify a complete ARN rather than a partial ARN.

"""
function restore_secret(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "RestoreSecret",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function restore_secret(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "RestoreSecret",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    rotate_secret(secret_id)
    rotate_secret(secret_id, params::Dict{String,<:Any})

Configures and starts the asynchronous process of rotating this secret. If you include the
configuration parameters, the operation sets those values for the secret and then
immediately starts a rotation. If you do not include the configuration parameters, the
operation starts a rotation with the values already stored in the secret. After the
rotation completes, the protected service and its clients all use the new version of the
secret.  This required configuration information includes the ARN of an Amazon Web Services
Lambda function and optionally, the time between scheduled rotations. The Lambda rotation
function creates a new version of the secret and creates or updates the credentials on the
protected service to match. After testing the new credentials, the function marks the new
secret with the staging label AWSCURRENT so that your clients all immediately begin to use
the new version. For more information about rotating secrets and how to configure a Lambda
function to rotate the secrets for your protected service, see Rotating Secrets in Amazon
Web Services Secrets Manager in the Amazon Web Services Secrets Manager User Guide. Secrets
Manager schedules the next rotation when the previous one completes. Secrets Manager
schedules the date by adding the rotation interval (number of days) to the actual date of
the last rotation. The service chooses the hour within that 24-hour date window randomly.
The minute is also chosen somewhat randomly, but weighted towards the top of the hour and
influenced by a variety of factors that help distribute load. The rotation function must
end with the versions of the secret in one of two states:   The AWSPENDING and AWSCURRENT
staging labels are attached to the same version of the secret, or   The AWSPENDING staging
label is not attached to any version of the secret.   If the AWSPENDING staging label is
present but not attached to the same version as AWSCURRENT then any later invocation of
RotateSecret assumes that a previous rotation request is still in progress and returns an
error.  Minimum permissions  To run this command, you must have the following permissions:
 secretsmanager:RotateSecret   lambda:InvokeFunction (on the function specified in the
secret's metadata)    Related operations    To list the secrets in your account, use
ListSecrets.   To get the details for a version of a secret, use DescribeSecret.   To
create a new version of a secret, use CreateSecret.   To attach staging labels to or remove
staging labels from a version of a secret, use UpdateSecretVersionStage.

# Arguments
- `secret_id`: Specifies the secret that you want to rotate. You can specify either the
  Amazon Resource Name (ARN) or the friendly name of the secret. For an ARN, we recommend
  that you specify a complete ARN rather than a partial ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientRequestToken"`: (Optional) Specifies a unique identifier for the new version of
  the secret that helps ensure idempotency.  If you use the Amazon Web Services CLI or one of
  the Amazon Web Services SDK to call this operation, then you can leave this parameter
  empty. The CLI or SDK generates a random UUID for you and includes that in the request for
  this parameter. If you don't use the SDK and instead generate a raw HTTP request to the
  Secrets Manager service endpoint, then you must generate a ClientRequestToken yourself for
  new versions and include that value in the request. You only need to specify your own value
  if you implement your own retry logic and want to ensure that a given secret is not created
  twice. We recommend that you generate a UUID-type value to ensure uniqueness within the
  specified secret.  Secrets Manager uses this value to prevent the accidental creation of
  duplicate versions if there are failures and retries during the function's processing. This
  value becomes the VersionId of the new version.
- `"RotationLambdaARN"`: (Optional) Specifies the ARN of the Lambda function that can
  rotate the secret.
- `"RotationRules"`: A structure that defines the rotation configuration for this secret.
"""
function rotate_secret(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "RotateSecret",
        Dict{String,Any}("SecretId" => SecretId, "ClientRequestToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function rotate_secret(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "RotateSecret",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "SecretId" => SecretId, "ClientRequestToken" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    stop_replication_to_replica(secret_id)
    stop_replication_to_replica(secret_id, params::Dict{String,<:Any})

Removes the secret from replication and promotes the secret to a regional secret in the
replica Region.

# Arguments
- `secret_id`: Response to StopReplicationToReplica of a secret, based on the SecretId.

"""
function stop_replication_to_replica(
    SecretId; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "StopReplicationToReplica",
        Dict{String,Any}("SecretId" => SecretId);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function stop_replication_to_replica(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "StopReplicationToReplica",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("SecretId" => SecretId), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    tag_resource(secret_id, tags)
    tag_resource(secret_id, tags, params::Dict{String,<:Any})

Attaches one or more tags, each consisting of a key name and a value, to the specified
secret. Tags are part of the secret's overall metadata, and are not associated with any
specific version of the secret. This operation only appends tags to the existing list of
tags. To remove tags, you must use UntagResource. The following basic restrictions apply to
tags:   Maximum number of tags per secret—50   Maximum key length—127 Unicode
characters in UTF-8   Maximum value length—255 Unicode characters in UTF-8   Tag keys and
values are case sensitive.   Do not use the aws: prefix in your tag names or values because
Amazon Web Services reserves it for Amazon Web Services use. You can't edit or delete tag
names or values with this prefix. Tags with this prefix do not count against your tags per
secret limit.   If you use your tagging schema across multiple services and resources,
remember other services might have restrictions on allowed characters. Generally allowed
characters: letters, spaces, and numbers representable in UTF-8, plus the following special
characters: + - = . _ : / @.    If you use tags as part of your security strategy, then
adding or removing a tag can change permissions. If successfully completing this operation
would result in you losing your permissions for this secret, then the operation is blocked
and returns an Access Denied error.   Minimum permissions  To run this command, you must
have the following permissions:   secretsmanager:TagResource    Related operations    To
remove one or more tags from the collection attached to a secret, use UntagResource.   To
view the list of tags attached to a secret, use DescribeSecret.

# Arguments
- `secret_id`: The identifier for the secret that you want to attach tags to. You can
  specify either the Amazon Resource Name (ARN) or the friendly name of the secret. For an
  ARN, we recommend that you specify a complete ARN rather than a partial ARN.
- `tags`: The tags to attach to the secret. Each element in the list consists of a Key and
  a Value. This parameter to the API requires a JSON text string argument. For storing
  multiple values, we recommend that you use a JSON text string argument and specify
  key/value pairs. For more information, see Specifying parameter values for the Amazon Web
  Services CLI in the Amazon Web Services CLI User Guide.

"""
function tag_resource(SecretId, Tags; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "TagResource",
        Dict{String,Any}("SecretId" => SecretId, "Tags" => Tags);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function tag_resource(
    SecretId,
    Tags,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "TagResource",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("SecretId" => SecretId, "Tags" => Tags), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    untag_resource(secret_id, tag_keys)
    untag_resource(secret_id, tag_keys, params::Dict{String,<:Any})

Removes one or more tags from the specified secret. This operation is idempotent. If a
requested tag is not attached to the secret, no error is returned and the secret metadata
is unchanged.  If you use tags as part of your security strategy, then removing a tag can
change permissions. If successfully completing this operation would result in you losing
your permissions for this secret, then the operation is blocked and returns an Access
Denied error.   Minimum permissions  To run this command, you must have the following
permissions:   secretsmanager:UntagResource    Related operations    To add one or more
tags to the collection attached to a secret, use TagResource.   To view the list of tags
attached to a secret, use DescribeSecret.

# Arguments
- `secret_id`: The identifier for the secret that you want to remove tags from. You can
  specify either the Amazon Resource Name (ARN) or the friendly name of the secret. For an
  ARN, we recommend that you specify a complete ARN rather than a partial ARN.
- `tag_keys`: A list of tag key names to remove from the secret. You don't specify the
  value. Both the key and its associated value are removed. This parameter to the API
  requires a JSON text string argument. For storing multiple values, we recommend that you
  use a JSON text string argument and specify key/value pairs. For more information, see
  Specifying parameter values for the Amazon Web Services CLI in the Amazon Web Services CLI
  User Guide.

"""
function untag_resource(
    SecretId, TagKeys; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "UntagResource",
        Dict{String,Any}("SecretId" => SecretId, "TagKeys" => TagKeys);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function untag_resource(
    SecretId,
    TagKeys,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "UntagResource",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("SecretId" => SecretId, "TagKeys" => TagKeys),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_secret(secret_id)
    update_secret(secret_id, params::Dict{String,<:Any})

Modifies many of the details of the specified secret.  To change the secret value, you can
also use PutSecretValue. To change the rotation configuration of a secret, use RotateSecret
instead. We recommend you avoid calling UpdateSecret at a sustained rate of more than once
every 10 minutes. When you call UpdateSecret to update the secret value, Secrets Manager
creates a new version of the secret. Secrets Manager removes outdated versions when there
are more than 100, but it does not remove versions created less than 24 hours ago. If you
update the secret value more than once every 10 minutes, you create more versions than
Secrets Manager removes, and you will reach the quota for secret versions.  The Secrets
Manager console uses only the SecretString parameter and therefore limits you to encrypting
and storing only a text string. To encrypt and store binary data as part of the version of
a secret, you must use either the Amazon Web Services CLI or one of the Amazon Web Services
SDKs.    If a version with a VersionId with the same value as the ClientRequestToken
parameter already exists, the operation results in an error. You cannot modify an existing
version, you can only create a new version.   If you include SecretString or SecretBinary
to create a new secret version, Secrets Manager automatically attaches the staging label
AWSCURRENT to the new version.       If you call an operation to encrypt or decrypt the
SecretString or SecretBinary for a secret in the same account as the calling user and that
secret doesn't specify a Amazon Web Services KMS encryption key, Secrets Manager uses the
account's default Amazon Web Services managed customer master key (CMK) with the alias
aws/secretsmanager. If this key doesn't already exist in your account then Secrets Manager
creates it for you automatically. All users and roles in the same Amazon Web Services
account automatically have access to use the default CMK. Note that if an Secrets Manager
API call results in Amazon Web Services creating the account's Amazon Web Services-managed
CMK, it can result in a one-time significant delay in returning the result.   If the secret
resides in a different Amazon Web Services account from the credentials calling an API that
requires encryption or decryption of the secret value then you must create and use a custom
Amazon Web Services KMS CMK because you can't access the default CMK for the account using
credentials from a different Amazon Web Services account. Store the ARN of the CMK in the
secret when you create the secret or when you update it by including it in the KMSKeyId. If
you call an API that must encrypt or decrypt SecretString or SecretBinary using credentials
from a different account then the Amazon Web Services KMS key policy must grant
cross-account access to that other account's user or role for both the kms:GenerateDataKey
and kms:Decrypt operations.     Minimum permissions  To run this command, you must have the
following permissions:   secretsmanager:UpdateSecret   kms:GenerateDataKey - needed only if
you use a custom Amazon Web Services KMS key to encrypt the secret. You do not need this
permission to use the account's Amazon Web Services managed CMK for Secrets Manager.
kms:Decrypt - needed only if you use a custom Amazon Web Services KMS key to encrypt the
secret. You do not need this permission to use the account's Amazon Web Services managed
CMK for Secrets Manager.    Related operations    To create a new secret, use CreateSecret.
  To add only a new version to an existing secret, use PutSecretValue.   To get the details
for a secret, use DescribeSecret.   To list the versions contained in a secret, use
ListSecretVersionIds.

# Arguments
- `secret_id`: Specifies the secret that you want to modify or to which you want to add a
  new version. You can specify either the Amazon Resource Name (ARN) or the friendly name of
  the secret. For an ARN, we recommend that you specify a complete ARN rather than a partial
  ARN.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"ClientRequestToken"`: (Optional) If you want to add a new version to the secret, this
  parameter specifies a unique identifier for the new version that helps ensure idempotency.
  If you use the Amazon Web Services CLI or one of the Amazon Web Services SDK to call this
  operation, then you can leave this parameter empty. The CLI or SDK generates a random UUID
  for you and includes that in the request. If you don't use the SDK and instead generate a
  raw HTTP request to the Secrets Manager service endpoint, then you must generate a
  ClientRequestToken yourself for new versions and include that value in the request. You
  typically only need to interact with this value if you implement your own retry logic and
  want to ensure that a given secret is not created twice. We recommend that you generate a
  UUID-type value to ensure uniqueness within the specified secret.  Secrets Manager uses
  this value to prevent the accidental creation of duplicate versions if there are failures
  and retries during the Lambda rotation function's processing.   If the ClientRequestToken
  value isn't already associated with a version of the secret then a new version of the
  secret is created.    If a version with this value already exists and that version's
  SecretString and SecretBinary values are the same as those in the request then the request
  is ignored (the operation is idempotent).    If a version with this value already exists
  and that version's SecretString and SecretBinary values are different from the request then
  an error occurs because you cannot modify an existing secret value.   This value becomes
  the VersionId of the new version.
- `"Description"`: (Optional) Specifies an updated user-provided description of the secret.
- `"KmsKeyId"`: (Optional) Specifies an updated ARN or alias of the Amazon Web Services KMS
  customer master key (CMK) that Secrets Manager uses to encrypt the protected text in new
  versions of this secret as well as any existing versions of this secret that have the
  staging labels AWSCURRENT, AWSPENDING, or AWSPREVIOUS. For more information about staging
  labels, see Staging Labels in the Amazon Web Services Secrets Manager User Guide.  You can
  only use the account's default CMK to encrypt and decrypt if you call this operation using
  credentials from the same account that owns the secret. If the secret is in a different
  account, then you must create a custom CMK and provide the ARN of that CMK in this field.
  The user making the call must have permissions to both the secret and the CMK in their
  respective accounts.
- `"SecretBinary"`: (Optional) Specifies updated binary data that you want to encrypt and
  store in the new version of the secret. To use this parameter in the command-line tools, we
  recommend that you store your binary data in a file and then use the appropriate technique
  for your tool to pass the contents of the file as a parameter. Either SecretBinary or
  SecretString must have a value, but not both. They cannot both be empty. This parameter is
  not accessible using the Secrets Manager console.
- `"SecretString"`: (Optional) Specifies updated text data that you want to encrypt and
  store in this new version of the secret. Either SecretBinary or SecretString must have a
  value, but not both. They cannot both be empty. If you create this secret by using the
  Secrets Manager console then Secrets Manager puts the protected secret text in only the
  SecretString parameter. The Secrets Manager console stores the information as a JSON
  structure of key/value pairs that the default Lambda rotation function knows how to parse.
  For storing multiple values, we recommend that you use a JSON text string argument and
  specify key/value pairs. For more information, see Specifying parameter values for the
  Amazon Web Services CLI in the Amazon Web Services CLI User Guide.
"""
function update_secret(SecretId; aws_config::AbstractAWSConfig=global_aws_config())
    return secrets_manager(
        "UpdateSecret",
        Dict{String,Any}("SecretId" => SecretId, "ClientRequestToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_secret(
    SecretId,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "UpdateSecret",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "SecretId" => SecretId, "ClientRequestToken" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_secret_version_stage(secret_id, version_stage)
    update_secret_version_stage(secret_id, version_stage, params::Dict{String,<:Any})

Modifies the staging labels attached to a version of a secret. Staging labels are used to
track a version as it progresses through the secret rotation process. You can attach a
staging label to only one version of a secret at a time. If a staging label to be added is
already attached to another version, then it is moved--removed from the other version first
and then attached to this one. For more information about staging labels, see Staging
Labels in the Amazon Web Services Secrets Manager User Guide.  The staging labels that you
specify in the VersionStage parameter are added to the existing list of staging
labels--they don't replace it. You can move the AWSCURRENT staging label to this version by
including it in this call.  Whenever you move AWSCURRENT, Secrets Manager automatically
moves the label AWSPREVIOUS to the version that AWSCURRENT was removed from.  If this
action results in the last label being removed from a version, then the version is
considered to be 'deprecated' and can be deleted by Secrets Manager.  Minimum permissions
To run this command, you must have the following permissions:
secretsmanager:UpdateSecretVersionStage    Related operations    To get the list of staging
labels that are currently associated with a version of a secret, use  DescribeSecret  and
examine the SecretVersionsToStages response value.

# Arguments
- `secret_id`: Specifies the secret with the version with the list of staging labels you
  want to modify. You can specify either the Amazon Resource Name (ARN) or the friendly name
  of the secret. For an ARN, we recommend that you specify a complete ARN rather than a
  partial ARN.
- `version_stage`: The staging label to add to this version.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MoveToVersionId"`: (Optional) The secret version ID that you want to add the staging
  label. If you want to remove a label from a version, then do not specify this parameter. If
  the staging label is already attached to a different version of the secret, then you must
  also specify the RemoveFromVersionId parameter.
- `"RemoveFromVersionId"`: Specifies the secret version ID of the version that the staging
  label is to be removed from. If the staging label you are trying to attach to one version
  is already attached to a different version, then you must include this parameter and
  specify the version that the label is to be removed from. If the label is attached and you
  either do not specify this parameter, or the version ID does not match, then the operation
  fails.
"""
function update_secret_version_stage(
    SecretId, VersionStage; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "UpdateSecretVersionStage",
        Dict{String,Any}("SecretId" => SecretId, "VersionStage" => VersionStage);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_secret_version_stage(
    SecretId,
    VersionStage,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "UpdateSecretVersionStage",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("SecretId" => SecretId, "VersionStage" => VersionStage),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    validate_resource_policy(resource_policy)
    validate_resource_policy(resource_policy, params::Dict{String,<:Any})

Validates that the resource policy does not grant a wide range of IAM principals access to
your secret. The JSON request string input and response output displays formatted code with
white space and line breaks for better readability. Submit your input as a single line JSON
string. A resource-based policy is optional for secrets. The API performs three checks when
validating the secret:   Sends a call to Zelkova, an automated reasoning engine, to ensure
your Resource Policy does not allow broad access to your secret.   Checks for correct
syntax in a policy.   Verifies the policy does not lock out a caller.    Minimum
Permissions  You must have the permissions required to access the following APIs:
secretsmanager:PutResourcePolicy     secretsmanager:ValidateResourcePolicy

# Arguments
- `resource_policy`: A JSON-formatted string constructed according to the grammar and
  syntax for an Amazon Web Services resource-based policy. The policy in the string
  identifies who can access or manage this secret and its versions. For information on how to
  format a JSON parameter for the various command line tool environments, see Using JSON for
  Parameters in the CLI User Guide.publi

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"SecretId"`:  (Optional) The identifier of the secret with the resource-based policy you
  want to validate. You can specify either the Amazon Resource Name (ARN) or the friendly
  name of the secret. For an ARN, we recommend that you specify a complete ARN rather than a
  partial ARN.
"""
function validate_resource_policy(
    ResourcePolicy; aws_config::AbstractAWSConfig=global_aws_config()
)
    return secrets_manager(
        "ValidateResourcePolicy",
        Dict{String,Any}("ResourcePolicy" => ResourcePolicy);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function validate_resource_policy(
    ResourcePolicy,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return secrets_manager(
        "ValidateResourcePolicy",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("ResourcePolicy" => ResourcePolicy), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
function iscorrelation(X::Matrix{<:AbstractFloat})
    all([
        isposdef(X),
        issymmetric(X),
        all(diag(X) .== one(eltype(X))),
        all(-one(eltype(X)) .≤ X .≤ one(eltype(X)))
    ])
end

for T in (Float64, Float32)
    @eval _normpdf(x::$T) = exp(-abs2(x)/2) * $T(invsqrt2π)
    @eval _normcdf(x::$T) = erfc(-x * $T(invsqrt2)) / 2
    @eval _norminvcdf(x::$T) = -$T(sqrt2) * erfcinv(2x)
end
for F in (:_normpdf, :_normcdf, :_norminvcdf)
    @eval $F(x::Float16) = Float16($F(Float32(x)))
end
for T in (Int16, Int32, Int64, Real)
    for F in (:_normpdf, :_normcdf, :_norminvcdf)
        @eval $F(x::$T) = $F(Float64(x))
    end
end

ext: jl


text:
export PolyhedralStartSolutionsIterator, update_cell!, mixed_volume

import MixedSubdivisions: MixedCell, MixedCellIterator, RegenerationTraverser, mixed_volume
import ElasticArrays: ElasticArray

#####################
## START SOLUTIONS ##
#####################

"""
    PolyhedralStartSolutionsIterator(f)

Creates an iterator over all mixed cells and their solutions corresponding to the polynomial
system `f`.
The iterator returns a tuple `(cell, X)` where `cell` is a `MixedCell` and
`X` is a `n × D` matrix containing the in each column a solution of the binomial
system corresponding to the mixed cell.

    PolyhedralStartSolutionsIterator(support)

Construct a polyhedral start solutions iterator by picking a random lifting
and random start coefficients.
"""
mutable struct PolyhedralStartSolutionsIterator{CT<:CoreTracker}
    support::Vector{Matrix{Int32}}
    start_coefficients::Vector{Vector{ComplexF64}}
    lifting::Union{Nothing,Vector{Vector{Int32}}}
    mixed_cells::Union{Nothing, Vector{MixedCell}} # all mixed_cells
    X::ElasticArray{ComplexF64, 2, 1} # solutions
    # Cache
    D::Matrix{Int} # binomial system lhs
    b::Vector{ComplexF64} # binomial system rhs
    H::Matrix{Int} # hermite normal form
    U::Matrix{Int} # trafo matrix for hnf
    γ::Vector{Float64} # angle of the elements in b
    μ::Vector{Float64} # γ^U
    S::ElasticArray{Int, 2, 1}
    αs::Vector{Float64} # partial angles in the triangular solve
    DT::Matrix{Float64} # transposed of D to solve coords
    # binomial homotopy fallback solution
    γU::Vector{Int}
    x::Vector{ComplexF64}
    αs_rational::Vector{Rational{Int}}
    binomial_tracker::CT
end

function PolyhedralStartSolutionsIterator(f::MPPolys)
    PolyhedralStartSolutionsIterator(MixedSubdivisions.support(f))
end
function PolyhedralStartSolutionsIterator(support::Vector{<:Matrix{<:Integer}})
    # Intuitively we want to sample the coefficients from the normal distribution
    # because we like this one very much.
    # But this yields to a bad surpise for the start solutions in the case that
    # the ratios of the coefficients in the binomial system is very different in between
    # the equations
    start_coefficients = map(A -> rand_approx_unit(size(A,2)), support)
    PolyhedralStartSolutionsIterator(convert(Vector{Matrix{Int32}}, support), start_coefficients)
end

"""
    rand_approx_unit(n::Integer)::Vector{ComplexF64}

This samples uniformly from the rectangle ``[0.9,1.1] × [0,2π]`` and transforms the sampled
values with the map ``(r, φ) ↦ r * e^{i φ}``.
"""
rand_approx_unit(n) = map(_ -> (0.9 + 0.2 * rand()) * cis(2π * rand()), 1:n)

function PolyhedralStartSolutionsIterator(
            support::Vector{Matrix{Int32}},
            start_coefficients::Vector{Vector{ComplexF64}})

    n = size(first(support), 1)
    D = zeros(Int, n, n)
    b = ones(ComplexF64, n)
    H = zeros(Int, n, n)
    U = zeros(Int, n, n)
    γ = ones(Float64, n)
    μ = zeros(Float64, n)
    X = ElasticArray{ComplexF64}(undef, n, 0)
    S = ElasticArray{Int}(undef, n, 0)
    αs = zeros(Float64, n)
    DT = zeros(Float64, n, n)

    γU = zeros(Int, n)
    x = randn(ComplexF64, n)
    αs_rational = Vector{Rational{Int64}}(undef, n)
    binomial_tracker = coretracker(BinomialHomotopy(D, b, γ), x;
                        affine_tracking=true,
                        initial_step_size=0.2,
                        predictor=Pade21())

    PolyhedralStartSolutionsIterator(support, start_coefficients, nothing, nothing,
            X, D, b, H, U, γ, μ, S, αs, DT, γU, x, αs_rational, binomial_tracker)
end

Base.IteratorSize(::Type{<:PolyhedralStartSolutionsIterator}) = Base.SizeUnknown()
Base.IteratorEltype(::Type{<:PolyhedralStartSolutionsIterator}) = Base.HasEltype()
Base.eltype(iter::PolyhedralStartSolutionsIterator) = Tuple{MixedCell, typeof(iter.X)}
function Base.length(iter::PolyhedralStartSolutionsIterator)
    compute_mixed_cells!(iter)
    sum(MixedSubdivisions.volume, iter.mixed_cells)
end

function compute_mixed_cells!(iter::PolyhedralStartSolutionsIterator)
    if isnothing(iter.mixed_cells) || isnothing(iter.lifting)
        res = MixedSubdivisions.fine_mixed_cells(iter.support)
        if isnothing(res)
            error("Cannot compute a start system due to technical limitations of our current implementation.")
        end
        mixed_cells, lifting = res
        iter.mixed_cells = mixed_cells
        iter.lifting = lifting
    end
    iter
end
function Base.iterate(iter::PolyhedralStartSolutionsIterator)
    compute_mixed_cells!(iter)

    isempty(iter.mixed_cells) && return nothing

    cell = iter.mixed_cells[1]
    cell_solutions!(iter, cell)

    return (cell, iter.X), 1
end

function Base.iterate(iter::PolyhedralStartSolutionsIterator, cell_number::Int)
    cell_number ≥ length(iter.mixed_cells) && return nothing

    cell = iter.mixed_cells[cell_number + 1]
    cell_solutions!(iter, cell)

    return (cell, iter.X), cell_number + 1
end

function cell_solutions!(iter::PolyhedralStartSolutionsIterator, cell::MixedCell)
    @unpack support, start_coefficients, D, b, H, U = iter
    n = length(iter.support)

    # setup system and compute hermite normal form
    construct_binomial_system!(D, b, support, start_coefficients, cell.indices)

    # This beauty tries first to compute the hnf using Int64,
    # then falls back to Int128 and finally gives up and just uses
    # BigInt
    try
        hnf!(H, U, D)
        cell_solutions!(iter, cell, H, U)
    catch e
        isa(e, OverflowError) || rethrow(e)
        try
            H128, U128 = hnf(D, Int128)
            cell_solutions!(iter, cell, H128, U128)
        catch e128
            isa(e128, OverflowError) || rethrow(e128)

            H_big, U_big = hnf(D, BigInt)
            cell_solutions!(iter, cell, H_big, U_big)
        end
    end

    nothing
end

function cell_solutions!(iter::PolyhedralStartSolutionsIterator, cell::MixedCell, H, U)
    @unpack D, b, γ, μ, X, S, DT = iter
    n = size(H, 1)
    # resize memory
    d̂ = cell.volume
    resize!(S, n, d̂)
    resize!(X, n, d̂)

    # setup a table of all combinations of the types of roots of unity we need
    fill_unit_roots_combinations!(S, H, d̂)

    cell_solutions_direct!(iter, cell, H, U)
    if !verify_solutions(iter)
        cell_solutions_homotopy!(iter, cell, H, U)
    end
end

function verify_solutions(iter)
    @unpack D, b, X = iter
    n = size(D,1)
    for k in 1:size(X,2)
        for i in 1:n
            yᵢ = one(X[1,k])
            for j in 1:n
                if D[j, i] != 0
                    yᵢ *= X[j,k]^D[j, i]
                end
            end
            abs(yᵢ - b[i]) < 1e-10 || return false
        end
    end
    true
end

function cell_solutions_direct!(iter::PolyhedralStartSolutionsIterator, cell::MixedCell, H, U)
    @unpack D, b, μ, X, DT = iter
    n = size(D,1)
    # We split the computation of the solution in 2 stages
    # 1) Compute solutions for the angular part -> d̂ many solutions
    compute_angular_part!(iter, cell, H, U)
    # 2) Solve for the absolute value
    μ .= log.(abs.(b))
    LinearAlgebra.transpose!(DT, D)
    LinearAlgebra.ldiv!(LinearAlgebra.lu!(DT), μ)
    μ .= exp.(μ)
    for j in 1:cell.volume, i in 1:n
        X[i, j] *= μ[i]
    end

    nothing
end

function fill_unit_roots_combinations!(S, H, d̂)
    n = size(H, 1)
    d, e = d̂, 1
    @inbounds for I in 1:n
        dᵢ = convert(Int64, H[I,I])
        d = d ÷ dᵢ
        k = 1
        for _ in 1:e, j in 0:(dᵢ-1), _ in 1:d
            S[I, k] = j
            k += 1
        end
        e *= dᵢ
    end
end

function compute_angular_part!(iter::PolyhedralStartSolutionsIterator, cell::MixedCell, H::Matrix{I}, U::Matrix{I}) where {I<:Union{Int64,Int128}}
    @unpack γ, b, μ, X, S, αs = iter
    n = length(iter.support)
    γ .= angle.(b) ./ (2π)
    apply_trafo_angles!(μ, γ, U)
    @inbounds for i in 1:cell.volume, j in n:-1:1
        α = μ[j] + S[j, i]
        for k in n:-1:(j+1)
            α -= αs[k] * H[k, j]
        end
        α /= H[j,j]
        X[j, i] = cis(2π * α)
        αs[j] = α
    end
end

function compute_angular_part!(iter::PolyhedralStartSolutionsIterator, cell::MixedCell, H::Matrix{BigInt}, U::Matrix{BigInt})
    @unpack b, γ, X, S = iter
    n = length(iter.support)
    μ = Vector{BigFloat}(undef, n)
    αs = Vector{BigFloat}(undef, n)
    γ .= angle.(b) ./ (2π)
    apply_trafo_angles!(μ, γ, U)
    @inbounds for i in 1:cell.volume, j in n:-1:1
        # This is always small in our applications
        α = μ[j] + S[j, i]
        for k in n:-1:(j+1)
            α -= αs[k] * H[k, j]
        end
        α /= H[j,j]
        X[j, i] = cis(2π * convert(Float64, mod(α, 1.0)))
        αs[j] = α
    end
end

function apply_trafo_angles!(μ, γ, U)
    n = length(γ)
    μ .= zero(eltype(μ))
    @inbounds for j in 1:n, i in 1:n
        μ[j] += U[i,j] * γ[i]
    end
    μ
end

function construct_binomial_system!(D, b, support, coeffs, indices)
    n = length(indices)
    @inbounds for i in 1:n
        aᵢ, bᵢ = indices[i]
        for j in 1:n
            D[j, i] = support[i][j, aᵢ] - support[i][j, bᵢ]
        end
        b[i] = -coeffs[i][bᵢ] / coeffs[i][aᵢ]
    end
    nothing
end

function cell_solutions_homotopy!(iter::PolyhedralStartSolutionsIterator, cell::MixedCell, H, U)
    @unpack D, b, γ, μ, X, γU, x, S, αs_rational, binomial_tracker = iter

    γ .= sign.(real.(b))
    apply_trafo!(γU, γ, U)

    n = size(D,1)
    for i in 1:cell.volume
        αs_denom = 1
        for j in n:-1:1
            α = S[j, i]
            denom = lcm(αs_denom, convert(Int, H[j,j]))
            if γU[j] == -1
                α += 1//2
                denom *= 2
            end
            for k in n:-1:(j+1)
                α -= αs_rational[k] * convert(Int, H[k, j] % denom)
            end
            α //= H[j,j]
            αs_denom = lcm(αs_denom, denominator(α))
            αs_rational[j] = (numerator(α) % denominator(α)) // denominator(α)
            x[j] = cis(2π * αs_rational[j])
        end

        ret = track!(binomial_tracker, x, 1.0, 0.0)
        x̄ = currx(binomial_tracker)
        for j in 1:n
            X[j,i] = x̄[j]
        end
    end

    nothing
end

function apply_trafo!(γU, γ, U)
    for i in 1:length(γ)
        γUᵢ = 1
        for j in 1:size(U,2)
            if γ[j] == -1 && isodd(U[j, i])
                γUᵢ = -γUᵢ
            end
        end
        γU[i] = γUᵢ
    end
    γU
end

#######################
# POLYHEDRAL TRACKER ##
#######################

"""
    PolyhedralTracker{CT<:CoreTracker, PT<:PathTracker, H<:ToricHomotopy}

The polyhedral tracker combines the tracking from toric infinity toward the target system
by a two-stage approach.
"""
struct PolyhedralTracker{CT<:CoreTracker, PT<:PathTracker, H<:ToricHomotopy}
    toric_homotopy::H
    toric_tracker::CT
    generic_tracker::PT
    # state
    s₀::Base.RefValue{Float64}
end

seed(PT::PolyhedralTracker) = PT.generic_tracker.problem.seed

function track!(PT::PolyhedralTracker, x∞)
    retcode = track!(PT.toric_tracker, x∞, PT.s₀[], 0.0)
    if retcode == CoreTrackerStatus.terminated_invalid_startvalue
        PT.s₀[] *= 2
        retcode = track!(PT.toric_tracker, x∞, PT.s₀[], 0.0)
    end
    if retcode != CoreTrackerStatus.success
        return PathTrackerStatus.status(retcode)
    end
    track!(PT.generic_tracker, currx(PT.toric_tracker))
end

@inline function PathResult(PT::PolyhedralTracker, args...; kwargs...)
    PathResult(PT.generic_tracker, args...; kwargs...)
end

function track(tracker::PolyhedralTracker, x₁; path_number::Int=1, details::Symbol=:default, kwargs...)
    track!(tracker, x₁; kwargs...)
    PathResult(tracker, x₁, path_number; details=details)
end

"""
    update_cell!(PT::PolyhedralTracker, cell::MixedCell)

Update the polyhedral tracker `PT` to track paths coming from the mixed cell `cell`.
"""
function update_cell!(PT::PolyhedralTracker, cell::MixedCell)
    min_weight = update_cell!(PT.toric_homotopy, cell)
    # We construct s₀ such that
    #   min_{1 ≤ i ≤ n} min_{aᵢ ∈ Aᵢ} exp(s₀ * w(aᵢ)+aᵢ⋅γ-βᵢ) = 10^-8
    # From this follows:
    PT.s₀[] = -8.0*log(10) / min_weight
    PT
end

function track_paths(PT::PolyhedralTracker, start_solutions::PolyhedralStartSolutionsIterator;
                threading=false, show_progress=true,
                path_result_details::Symbol=:default, save_all_paths=false)
    results = Vector{result_type(PT.generic_tracker)}()

    compute_mixed_cells!(start_solutions)
    update_lifting!(PT.toric_homotopy, start_solutions.lifting)

    n = length(start_solutions)
    if show_progress
        progress = ProgressMeter.Progress(n, 0.1, "Tracking $n paths... ")
    else
        progress = nothing
    end

    stats = SolveStats()
    ntracked = 1
    try
        nthreads = Threads.nthreads()
        if threading && nthreads > 1
            @warn "Multithreading is currently not supported with polyhedral homotopy, the computation runs only with a single thread."
        end
        for (cell, X) in start_solutions
            update_cell!(PT, cell)
            for i in 1:size(X, 2)
                x∞ = @view X[:,i]

                return_code = track!(PT, x∞)
                if save_all_paths || return_code == PathTrackerStatus.success
                    R = PathResult(PT, x∞, ntracked; details=path_result_details)
                    push!(results, R)

                    if return_code == PathTrackerStatus.success
                        update!(stats, R)
                    end
                end
                ntracked += 1
                if ntracked % 32 == 0
                    if progress !== nothing
                        update_progress!(progress, ntracked, stats)
                    end
                end
            end
        end
        if progress !== nothing
            update_progress!(progress, ntracked - 1, stats; finished=true)
        end
    catch e
        if isa(e, InterruptException)
            return results, ntracked
        else
            rethrow(e)
        end
    end
    results, ntracked - 1
end

function tracker_startsolutions(prob::PolyhedralProblem, startsolutions::PolyhedralStartSolutionsIterator; kwargs...)
    x = randn(ComplexF64, size(prob.toric_homotopy)[2])
    toric_tracker =
        coretracker(prob.toric_homotopy, [x]; seed=prob.seed, affine_tracking=true, predictor=Pade21())
    generic_prob = target_problem(prob)
    generic_tracker, _ =
        tracker_startsolutions(generic_prob, startsolutions; kwargs...)
    tracker = PolyhedralTracker(prob.toric_homotopy, toric_tracker, generic_tracker, Ref(NaN))
    (tracker=tracker, startsolutions=startsolutions)
end

function target_problem(P::PolyhedralProblem)
	Problem(P.tracking_type, P.generic_homotopy, P.vargroups,
				P.seed, P.startsolutions_need_reordering, P.regauging_factors)
end

function start_solution_sample(iter::PolyhedralStartSolutionsIterator)
    randn(ComplexF64, size(iter.X, 1))
end