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

using AWS.Compat
using AWS.UUIDs
"""
    AssociateFleet()

Associates the specified fleet with the specified stack.

# Required Parameters
- `FleetName`: The name of the fleet.
- `StackName`: The name of the stack.

"""

associate_fleet(FleetName, StackName; aws_config::AWSConfig=global_aws_config()) = appstream("AssociateFleet", Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName); aws_config=aws_config)
associate_fleet(FleetName, StackName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("AssociateFleet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName), args)); aws_config=aws_config)

"""
    BatchAssociateUserStack()

Associates the specified users with the specified stacks. Users in a user pool cannot be assigned to stacks with fleets that are joined to an Active Directory domain.

# Required Parameters
- `UserStackAssociations`: The list of UserStackAssociation objects.

"""

batch_associate_user_stack(UserStackAssociations; aws_config::AWSConfig=global_aws_config()) = appstream("BatchAssociateUserStack", Dict{String, Any}("UserStackAssociations"=>UserStackAssociations); aws_config=aws_config)
batch_associate_user_stack(UserStackAssociations, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("BatchAssociateUserStack", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("UserStackAssociations"=>UserStackAssociations), args)); aws_config=aws_config)

"""
    BatchDisassociateUserStack()

Disassociates the specified users from the specified stacks.

# Required Parameters
- `UserStackAssociations`: The list of UserStackAssociation objects.

"""

batch_disassociate_user_stack(UserStackAssociations; aws_config::AWSConfig=global_aws_config()) = appstream("BatchDisassociateUserStack", Dict{String, Any}("UserStackAssociations"=>UserStackAssociations); aws_config=aws_config)
batch_disassociate_user_stack(UserStackAssociations, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("BatchDisassociateUserStack", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("UserStackAssociations"=>UserStackAssociations), args)); aws_config=aws_config)

"""
    CopyImage()

Copies the image within the same region or to a new region within the same AWS account. Note that any tags you added to the image will not be copied.

# Required Parameters
- `DestinationImageName`: The name that the image will have when it is copied to the destination.
- `DestinationRegion`: The destination region to which the image will be copied. This parameter is required, even if you are copying an image within the same region.
- `SourceImageName`: The name of the image to copy.

# Optional Parameters
- `DestinationImageDescription`: The description that the image will have when it is copied to the destination.
"""

copy_image(DestinationImageName, DestinationRegion, SourceImageName; aws_config::AWSConfig=global_aws_config()) = appstream("CopyImage", Dict{String, Any}("DestinationImageName"=>DestinationImageName, "DestinationRegion"=>DestinationRegion, "SourceImageName"=>SourceImageName); aws_config=aws_config)
copy_image(DestinationImageName, DestinationRegion, SourceImageName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CopyImage", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DestinationImageName"=>DestinationImageName, "DestinationRegion"=>DestinationRegion, "SourceImageName"=>SourceImageName), args)); aws_config=aws_config)

"""
    CreateDirectoryConfig()

Creates a Directory Config object in AppStream 2.0. This object includes the configuration information required to join fleets and image builders to Microsoft Active Directory domains.

# Required Parameters
- `DirectoryName`: The fully qualified name of the directory (for example, corp.example.com).
- `OrganizationalUnitDistinguishedNames`: The distinguished names of the organizational units for computer accounts.

# Optional Parameters
- `ServiceAccountCredentials`: The credentials for the service account used by the fleet or image builder to connect to the directory.
"""

create_directory_config(DirectoryName, OrganizationalUnitDistinguishedNames; aws_config::AWSConfig=global_aws_config()) = appstream("CreateDirectoryConfig", Dict{String, Any}("DirectoryName"=>DirectoryName, "OrganizationalUnitDistinguishedNames"=>OrganizationalUnitDistinguishedNames); aws_config=aws_config)
create_directory_config(DirectoryName, OrganizationalUnitDistinguishedNames, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateDirectoryConfig", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DirectoryName"=>DirectoryName, "OrganizationalUnitDistinguishedNames"=>OrganizationalUnitDistinguishedNames), args)); aws_config=aws_config)

"""
    CreateFleet()

Creates a fleet. A fleet consists of streaming instances that run a specified image.

# Required Parameters
- `ComputeCapacity`: The desired capacity for the fleet.
- `InstanceType`: The instance type to use when launching fleet instances. The following instance types are available:   stream.standard.medium   stream.standard.large   stream.compute.large   stream.compute.xlarge   stream.compute.2xlarge   stream.compute.4xlarge   stream.compute.8xlarge   stream.memory.large   stream.memory.xlarge   stream.memory.2xlarge   stream.memory.4xlarge   stream.memory.8xlarge   stream.memory.z1d.large   stream.memory.z1d.xlarge   stream.memory.z1d.2xlarge   stream.memory.z1d.3xlarge   stream.memory.z1d.6xlarge   stream.memory.z1d.12xlarge   stream.graphics-design.large   stream.graphics-design.xlarge   stream.graphics-design.2xlarge   stream.graphics-design.4xlarge   stream.graphics-desktop.2xlarge   stream.graphics.g4dn.xlarge   stream.graphics.g4dn.2xlarge   stream.graphics.g4dn.4xlarge   stream.graphics.g4dn.8xlarge   stream.graphics.g4dn.12xlarge   stream.graphics.g4dn.16xlarge   stream.graphics-pro.4xlarge   stream.graphics-pro.8xlarge   stream.graphics-pro.16xlarge
- `Name`: A unique name for the fleet.

# Optional Parameters
- `Description`: The description to display.
- `DisconnectTimeoutInSeconds`: The amount of time that a streaming session remains active after users disconnect. If users try to reconnect to the streaming session after a disconnection or network interruption within this time interval, they are connected to their previous session. Otherwise, they are connected to a new session with a new streaming instance.  Specify a value between 60 and 360000.
- `DisplayName`: The fleet name to display.
- `DomainJoinInfo`: The name of the directory and organizational unit (OU) to use to join the fleet to a Microsoft Active Directory domain.
- `EnableDefaultInternetAccess`: Enables or disables default internet access for the fleet.
- `FleetType`: The fleet type.  ALWAYS_ON  Provides users with instant-on access to their apps. You are charged for all running instances in your fleet, even if no users are streaming apps.  ON_DEMAND  Provide users with access to applications after they connect, which takes one to two minutes. You are charged for instance streaming when users are connected and a small hourly fee for instances that are not streaming apps.
- `IamRoleArn`: The Amazon Resource Name (ARN) of the IAM role to apply to the fleet. To assume a role, a fleet instance calls the AWS Security Token Service (STS) AssumeRole API operation and passes the ARN of the role to use. The operation creates a new session with temporary credentials. AppStream 2.0 retrieves the temporary credentials and creates the appstream_machine_role credential profile on the instance. For more information, see Using an IAM Role to Grant Permissions to Applications and Scripts Running on AppStream 2.0 Streaming Instances in the Amazon AppStream 2.0 Administration Guide.
- `IdleDisconnectTimeoutInSeconds`: The amount of time that users can be idle (inactive) before they are disconnected from their streaming session and the DisconnectTimeoutInSeconds time interval begins. Users are notified before they are disconnected due to inactivity. If they try to reconnect to the streaming session before the time interval specified in DisconnectTimeoutInSeconds elapses, they are connected to their previous session. Users are considered idle when they stop providing keyboard or mouse input during their streaming session. File uploads and downloads, audio in, audio out, and pixels changing do not qualify as user activity. If users continue to be idle after the time interval in IdleDisconnectTimeoutInSeconds elapses, they are disconnected. To prevent users from being disconnected due to inactivity, specify a value of 0. Otherwise, specify a value between 60 and 3600. The default value is 0.  If you enable this feature, we recommend that you specify a value that corresponds exactly to a whole number of minutes (for example, 60, 120, and 180). If you don't do this, the value is rounded to the nearest minute. For example, if you specify a value of 70, users are disconnected after 1 minute of inactivity. If you specify a value that is at the midpoint between two different minutes, the value is rounded up. For example, if you specify a value of 90, users are disconnected after 2 minutes of inactivity.
- `ImageArn`: The ARN of the public, private, or shared image to use.
- `ImageName`: The name of the image used to create the fleet.
- `MaxUserDurationInSeconds`: The maximum amount of time that a streaming session can remain active, in seconds. If users are still connected to a streaming instance five minutes before this limit is reached, they are prompted to save any open documents before being disconnected. After this time elapses, the instance is terminated and replaced by a new instance. Specify a value between 600 and 360000.
- `StreamView`: The AppStream 2.0 view that is displayed to your users when they stream from the fleet. When APP is specified, only the windows of applications opened by users display. When DESKTOP is specified, the standard desktop that is provided by the operating system displays. The default value is APP.
- `Tags`: The tags to associate with the fleet. A tag is a key-value pair, and the value is optional. For example, Environment=Test. If you do not specify a value, Environment=.  If you do not specify a value, the value is set to an empty string. Generally allowed characters are: letters, numbers, and spaces representable in UTF-8, and the following special characters:  _ . : / = +  - @ For more information, see Tagging Your Resources in the Amazon AppStream 2.0 Administration Guide.
- `VpcConfig`: The VPC configuration for the fleet.
"""

create_fleet(ComputeCapacity, InstanceType, Name; aws_config::AWSConfig=global_aws_config()) = appstream("CreateFleet", Dict{String, Any}("ComputeCapacity"=>ComputeCapacity, "InstanceType"=>InstanceType, "Name"=>Name); aws_config=aws_config)
create_fleet(ComputeCapacity, InstanceType, Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateFleet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ComputeCapacity"=>ComputeCapacity, "InstanceType"=>InstanceType, "Name"=>Name), args)); aws_config=aws_config)

"""
    CreateImageBuilder()

Creates an image builder. An image builder is a virtual machine that is used to create an image. The initial state of the builder is PENDING. When it is ready, the state is RUNNING.

# Required Parameters
- `InstanceType`: The instance type to use when launching the image builder. The following instance types are available:   stream.standard.medium   stream.standard.large   stream.compute.large   stream.compute.xlarge   stream.compute.2xlarge   stream.compute.4xlarge   stream.compute.8xlarge   stream.memory.large   stream.memory.xlarge   stream.memory.2xlarge   stream.memory.4xlarge   stream.memory.8xlarge   stream.memory.z1d.large   stream.memory.z1d.xlarge   stream.memory.z1d.2xlarge   stream.memory.z1d.3xlarge   stream.memory.z1d.6xlarge   stream.memory.z1d.12xlarge   stream.graphics-design.large   stream.graphics-design.xlarge   stream.graphics-design.2xlarge   stream.graphics-design.4xlarge   stream.graphics-desktop.2xlarge   stream.graphics.g4dn.xlarge   stream.graphics.g4dn.2xlarge   stream.graphics.g4dn.4xlarge   stream.graphics.g4dn.8xlarge   stream.graphics.g4dn.12xlarge   stream.graphics.g4dn.16xlarge   stream.graphics-pro.4xlarge   stream.graphics-pro.8xlarge   stream.graphics-pro.16xlarge
- `Name`: A unique name for the image builder.

# Optional Parameters
- `AccessEndpoints`: The list of interface VPC endpoint (interface endpoint) objects. Administrators can connect to the image builder only through the specified endpoints.
- `AppstreamAgentVersion`: The version of the AppStream 2.0 agent to use for this image builder. To use the latest version of the AppStream 2.0 agent, specify [LATEST].
- `Description`: The description to display.
- `DisplayName`: The image builder name to display.
- `DomainJoinInfo`: The name of the directory and organizational unit (OU) to use to join the image builder to a Microsoft Active Directory domain.
- `EnableDefaultInternetAccess`: Enables or disables default internet access for the image builder.
- `IamRoleArn`: The Amazon Resource Name (ARN) of the IAM role to apply to the image builder. To assume a role, the image builder calls the AWS Security Token Service (STS) AssumeRole API operation and passes the ARN of the role to use. The operation creates a new session with temporary credentials. AppStream 2.0 retrieves the temporary credentials and creates the appstream_machine_role credential profile on the instance. For more information, see Using an IAM Role to Grant Permissions to Applications and Scripts Running on AppStream 2.0 Streaming Instances in the Amazon AppStream 2.0 Administration Guide.
- `ImageArn`: The ARN of the public, private, or shared image to use.
- `ImageName`: The name of the image used to create the image builder.
- `Tags`: The tags to associate with the image builder. A tag is a key-value pair, and the value is optional. For example, Environment=Test. If you do not specify a value, Environment=.  Generally allowed characters are: letters, numbers, and spaces representable in UTF-8, and the following special characters:  _ . : / = +  - @ If you do not specify a value, the value is set to an empty string. For more information about tags, see Tagging Your Resources in the Amazon AppStream 2.0 Administration Guide.
- `VpcConfig`: The VPC configuration for the image builder. You can specify only one subnet.
"""

create_image_builder(InstanceType, Name; aws_config::AWSConfig=global_aws_config()) = appstream("CreateImageBuilder", Dict{String, Any}("InstanceType"=>InstanceType, "Name"=>Name); aws_config=aws_config)
create_image_builder(InstanceType, Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateImageBuilder", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("InstanceType"=>InstanceType, "Name"=>Name), args)); aws_config=aws_config)

"""
    CreateImageBuilderStreamingURL()

Creates a URL to start an image builder streaming session.

# Required Parameters
- `Name`: The name of the image builder.

# Optional Parameters
- `Validity`: The time that the streaming URL will be valid, in seconds. Specify a value between 1 and 604800 seconds. The default is 3600 seconds.
"""

create_image_builder_streaming_url(Name; aws_config::AWSConfig=global_aws_config()) = appstream("CreateImageBuilderStreamingURL", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
create_image_builder_streaming_url(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateImageBuilderStreamingURL", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    CreateStack()

Creates a stack to start streaming applications to users. A stack consists of an associated fleet, user access policies, and storage configurations.

# Required Parameters
- `Name`: The name of the stack.

# Optional Parameters
- `AccessEndpoints`: The list of interface VPC endpoint (interface endpoint) objects. Users of the stack can connect to AppStream 2.0 only through the specified endpoints.
- `ApplicationSettings`: The persistent application settings for users of a stack. When these settings are enabled, changes that users make to applications and Windows settings are automatically saved after each session and applied to the next session.
- `Description`: The description to display.
- `DisplayName`: The stack name to display.
- `EmbedHostDomains`: The domains where AppStream 2.0 streaming sessions can be embedded in an iframe. You must approve the domains that you want to host embedded AppStream 2.0 streaming sessions.
- `FeedbackURL`: The URL that users are redirected to after they click the Send Feedback link. If no URL is specified, no Send Feedback link is displayed.
- `RedirectURL`: The URL that users are redirected to after their streaming session ends.
- `StorageConnectors`: The storage connectors to enable.
- `Tags`: The tags to associate with the stack. A tag is a key-value pair, and the value is optional. For example, Environment=Test. If you do not specify a value, Environment=.  If you do not specify a value, the value is set to an empty string. Generally allowed characters are: letters, numbers, and spaces representable in UTF-8, and the following special characters:  _ . : / = +  - @ For more information about tags, see Tagging Your Resources in the Amazon AppStream 2.0 Administration Guide.
- `UserSettings`: The actions that are enabled or disabled for users during their streaming sessions. By default, these actions are enabled.
"""

create_stack(Name; aws_config::AWSConfig=global_aws_config()) = appstream("CreateStack", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
create_stack(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateStack", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    CreateStreamingURL()

Creates a temporary URL to start an AppStream 2.0 streaming session for the specified user. A streaming URL enables application streaming to be tested without user setup.

# Required Parameters
- `FleetName`: The name of the fleet.
- `StackName`: The name of the stack.
- `UserId`: The identifier of the user.

# Optional Parameters
- `ApplicationId`: The name of the application to launch after the session starts. This is the name that you specified as Name in the Image Assistant.
- `SessionContext`: The session context. For more information, see Session Context in the Amazon AppStream 2.0 Administration Guide.
- `Validity`: The time that the streaming URL will be valid, in seconds. Specify a value between 1 and 604800 seconds. The default is 60 seconds.
"""

create_streaming_url(FleetName, StackName, UserId; aws_config::AWSConfig=global_aws_config()) = appstream("CreateStreamingURL", Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName, "UserId"=>UserId); aws_config=aws_config)
create_streaming_url(FleetName, StackName, UserId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateStreamingURL", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName, "UserId"=>UserId), args)); aws_config=aws_config)

"""
    CreateUsageReportSubscription()

Creates a usage report subscription. Usage reports are generated daily.

"""

create_usage_report_subscription(; aws_config::AWSConfig=global_aws_config()) = appstream("CreateUsageReportSubscription"; aws_config=aws_config)
create_usage_report_subscription(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateUsageReportSubscription", args; aws_config=aws_config)

"""
    CreateUser()

Creates a new user in the user pool.

# Required Parameters
- `AuthenticationType`: The authentication type for the user. You must specify USERPOOL.
- `UserName`: The email address of the user.  Users' email addresses are case-sensitive. During login, if they specify an email address that doesn't use the same capitalization as the email address specified when their user pool account was created, a \"user does not exist\" error message displays.

# Optional Parameters
- `FirstName`: The first name, or given name, of the user.
- `LastName`: The last name, or surname, of the user.
- `MessageAction`: The action to take for the welcome email that is sent to a user after the user is created in the user pool. If you specify SUPPRESS, no email is sent. If you specify RESEND, do not specify the first name or last name of the user. If the value is null, the email is sent.   The temporary password in the welcome email is valid for only 7 days. If users don’t set their passwords within 7 days, you must send them a new welcome email.
"""

create_user(AuthenticationType, UserName; aws_config::AWSConfig=global_aws_config()) = appstream("CreateUser", Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName); aws_config=aws_config)
create_user(AuthenticationType, UserName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("CreateUser", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName), args)); aws_config=aws_config)

"""
    DeleteDirectoryConfig()

Deletes the specified Directory Config object from AppStream 2.0. This object includes the information required to join streaming instances to an Active Directory domain.

# Required Parameters
- `DirectoryName`: The name of the directory configuration.

"""

delete_directory_config(DirectoryName; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteDirectoryConfig", Dict{String, Any}("DirectoryName"=>DirectoryName); aws_config=aws_config)
delete_directory_config(DirectoryName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteDirectoryConfig", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DirectoryName"=>DirectoryName), args)); aws_config=aws_config)

"""
    DeleteFleet()

Deletes the specified fleet.

# Required Parameters
- `Name`: The name of the fleet.

"""

delete_fleet(Name; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteFleet", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
delete_fleet(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteFleet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    DeleteImage()

Deletes the specified image. You cannot delete an image when it is in use. After you delete an image, you cannot provision new capacity using the image.

# Required Parameters
- `Name`: The name of the image.

"""

delete_image(Name; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteImage", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
delete_image(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteImage", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    DeleteImageBuilder()

Deletes the specified image builder and releases the capacity.

# Required Parameters
- `Name`: The name of the image builder.

"""

delete_image_builder(Name; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteImageBuilder", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
delete_image_builder(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteImageBuilder", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    DeleteImagePermissions()

Deletes permissions for the specified private image. After you delete permissions for an image, AWS accounts to which you previously granted these permissions can no longer use the image.

# Required Parameters
- `Name`: The name of the private image.
- `SharedAccountId`: The 12-digit identifier of the AWS account for which to delete image permissions.

"""

delete_image_permissions(Name, SharedAccountId; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteImagePermissions", Dict{String, Any}("Name"=>Name, "SharedAccountId"=>SharedAccountId); aws_config=aws_config)
delete_image_permissions(Name, SharedAccountId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteImagePermissions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name, "SharedAccountId"=>SharedAccountId), args)); aws_config=aws_config)

"""
    DeleteStack()

Deletes the specified stack. After the stack is deleted, the application streaming environment provided by the stack is no longer available to users. Also, any reservations made for application streaming sessions for the stack are released.

# Required Parameters
- `Name`: The name of the stack.

"""

delete_stack(Name; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteStack", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
delete_stack(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteStack", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    DeleteUsageReportSubscription()

Disables usage report generation.

"""

delete_usage_report_subscription(; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteUsageReportSubscription"; aws_config=aws_config)
delete_usage_report_subscription(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteUsageReportSubscription", args; aws_config=aws_config)

"""
    DeleteUser()

Deletes a user from the user pool.

# Required Parameters
- `AuthenticationType`: The authentication type for the user. You must specify USERPOOL.
- `UserName`: The email address of the user.  Users' email addresses are case-sensitive.

"""

delete_user(AuthenticationType, UserName; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteUser", Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName); aws_config=aws_config)
delete_user(AuthenticationType, UserName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DeleteUser", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName), args)); aws_config=aws_config)

"""
    DescribeDirectoryConfigs()

Retrieves a list that describes one or more specified Directory Config objects for AppStream 2.0, if the names for these objects are provided. Otherwise, all Directory Config objects in the account are described. These objects include the configuration information required to join fleets and image builders to Microsoft Active Directory domains.  Although the response syntax in this topic includes the account password, this password is not returned in the actual response.

# Optional Parameters
- `DirectoryNames`: The directory names.
- `MaxResults`: The maximum size of each page of results.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

describe_directory_configs(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeDirectoryConfigs"; aws_config=aws_config)
describe_directory_configs(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeDirectoryConfigs", args; aws_config=aws_config)

"""
    DescribeFleets()

Retrieves a list that describes one or more specified fleets, if the fleet names are provided. Otherwise, all fleets in the account are described.

# Optional Parameters
- `Names`: The names of the fleets to describe.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

describe_fleets(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeFleets"; aws_config=aws_config)
describe_fleets(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeFleets", args; aws_config=aws_config)

"""
    DescribeImageBuilders()

Retrieves a list that describes one or more specified image builders, if the image builder names are provided. Otherwise, all image builders in the account are described.

# Optional Parameters
- `MaxResults`: The maximum size of each page of results.
- `Names`: The names of the image builders to describe.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

describe_image_builders(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeImageBuilders"; aws_config=aws_config)
describe_image_builders(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeImageBuilders", args; aws_config=aws_config)

"""
    DescribeImagePermissions()

Retrieves a list that describes the permissions for shared AWS account IDs on a private image that you own.

# Required Parameters
- `Name`: The name of the private image for which to describe permissions. The image must be one that you own.

# Optional Parameters
- `MaxResults`: The maximum size of each page of results.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
- `SharedAwsAccountIds`: The 12-digit identifier of one or more AWS accounts with which the image is shared.
"""

describe_image_permissions(Name; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeImagePermissions", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
describe_image_permissions(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeImagePermissions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    DescribeImages()

Retrieves a list that describes one or more specified images, if the image names or image ARNs are provided. Otherwise, all images in the account are described.

# Optional Parameters
- `Arns`: The ARNs of the public, private, and shared images to describe.
- `MaxResults`: The maximum size of each page of results.
- `Names`: The names of the public or private images to describe.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
- `Type`: The type of image (public, private, or shared) to describe.
"""

describe_images(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeImages"; aws_config=aws_config)
describe_images(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeImages", args; aws_config=aws_config)

"""
    DescribeSessions()

Retrieves a list that describes the streaming sessions for a specified stack and fleet. If a UserId is provided for the stack and fleet, only streaming sessions for that user are described. If an authentication type is not provided, the default is to authenticate users using a streaming URL.

# Required Parameters
- `FleetName`: The name of the fleet. This value is case-sensitive.
- `StackName`: The name of the stack. This value is case-sensitive.

# Optional Parameters
- `AuthenticationType`: The authentication method. Specify API for a user authenticated using a streaming URL or SAML for a SAML federated user. The default is to authenticate users using a streaming URL.
- `Limit`: The size of each page of results. The default value is 20 and the maximum value is 50.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
- `UserId`: The user identifier (ID). If you specify a user ID, you must also specify the authentication type.
"""

describe_sessions(FleetName, StackName; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeSessions", Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName); aws_config=aws_config)
describe_sessions(FleetName, StackName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeSessions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName), args)); aws_config=aws_config)

"""
    DescribeStacks()

Retrieves a list that describes one or more specified stacks, if the stack names are provided. Otherwise, all stacks in the account are described.

# Optional Parameters
- `Names`: The names of the stacks to describe.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

describe_stacks(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeStacks"; aws_config=aws_config)
describe_stacks(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeStacks", args; aws_config=aws_config)

"""
    DescribeUsageReportSubscriptions()

Retrieves a list that describes one or more usage report subscriptions.

# Optional Parameters
- `MaxResults`: The maximum size of each page of results.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

describe_usage_report_subscriptions(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeUsageReportSubscriptions"; aws_config=aws_config)
describe_usage_report_subscriptions(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeUsageReportSubscriptions", args; aws_config=aws_config)

"""
    DescribeUserStackAssociations()

Retrieves a list that describes the UserStackAssociation objects. You must specify either or both of the following:   The stack name   The user name (email address of the user associated with the stack) and the authentication type for the user

# Optional Parameters
- `AuthenticationType`: The authentication type for the user who is associated with the stack. You must specify USERPOOL.
- `MaxResults`: The maximum size of each page of results.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
- `StackName`: The name of the stack that is associated with the user.
- `UserName`: The email address of the user who is associated with the stack.  Users' email addresses are case-sensitive.
"""

describe_user_stack_associations(; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeUserStackAssociations"; aws_config=aws_config)
describe_user_stack_associations(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeUserStackAssociations", args; aws_config=aws_config)

"""
    DescribeUsers()

Retrieves a list that describes one or more specified users in the user pool.

# Required Parameters
- `AuthenticationType`: The authentication type for the users in the user pool to describe. You must specify USERPOOL.

# Optional Parameters
- `MaxResults`: The maximum size of each page of results.
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

describe_users(AuthenticationType; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeUsers", Dict{String, Any}("AuthenticationType"=>AuthenticationType); aws_config=aws_config)
describe_users(AuthenticationType, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DescribeUsers", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AuthenticationType"=>AuthenticationType), args)); aws_config=aws_config)

"""
    DisableUser()

Disables the specified user in the user pool. Users can't sign in to AppStream 2.0 until they are re-enabled. This action does not delete the user.

# Required Parameters
- `AuthenticationType`: The authentication type for the user. You must specify USERPOOL.
- `UserName`: The email address of the user.  Users' email addresses are case-sensitive.

"""

disable_user(AuthenticationType, UserName; aws_config::AWSConfig=global_aws_config()) = appstream("DisableUser", Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName); aws_config=aws_config)
disable_user(AuthenticationType, UserName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DisableUser", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName), args)); aws_config=aws_config)

"""
    DisassociateFleet()

Disassociates the specified fleet from the specified stack.

# Required Parameters
- `FleetName`: The name of the fleet.
- `StackName`: The name of the stack.

"""

disassociate_fleet(FleetName, StackName; aws_config::AWSConfig=global_aws_config()) = appstream("DisassociateFleet", Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName); aws_config=aws_config)
disassociate_fleet(FleetName, StackName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("DisassociateFleet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("FleetName"=>FleetName, "StackName"=>StackName), args)); aws_config=aws_config)

"""
    EnableUser()

Enables a user in the user pool. After being enabled, users can sign in to AppStream 2.0 and open applications from the stacks to which they are assigned.

# Required Parameters
- `AuthenticationType`: The authentication type for the user. You must specify USERPOOL.
- `UserName`: The email address of the user.  Users' email addresses are case-sensitive. During login, if they specify an email address that doesn't use the same capitalization as the email address specified when their user pool account was created, a \"user does not exist\" error message displays.

"""

enable_user(AuthenticationType, UserName; aws_config::AWSConfig=global_aws_config()) = appstream("EnableUser", Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName); aws_config=aws_config)
enable_user(AuthenticationType, UserName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("EnableUser", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AuthenticationType"=>AuthenticationType, "UserName"=>UserName), args)); aws_config=aws_config)

"""
    ExpireSession()

Immediately stops the specified streaming session.

# Required Parameters
- `SessionId`: The identifier of the streaming session.

"""

expire_session(SessionId; aws_config::AWSConfig=global_aws_config()) = appstream("ExpireSession", Dict{String, Any}("SessionId"=>SessionId); aws_config=aws_config)
expire_session(SessionId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("ExpireSession", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("SessionId"=>SessionId), args)); aws_config=aws_config)

"""
    ListAssociatedFleets()

Retrieves the name of the fleet that is associated with the specified stack.

# Required Parameters
- `StackName`: The name of the stack.

# Optional Parameters
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

list_associated_fleets(StackName; aws_config::AWSConfig=global_aws_config()) = appstream("ListAssociatedFleets", Dict{String, Any}("StackName"=>StackName); aws_config=aws_config)
list_associated_fleets(StackName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("ListAssociatedFleets", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("StackName"=>StackName), args)); aws_config=aws_config)

"""
    ListAssociatedStacks()

Retrieves the name of the stack with which the specified fleet is associated.

# Required Parameters
- `FleetName`: The name of the fleet.

# Optional Parameters
- `NextToken`: The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.
"""

list_associated_stacks(FleetName; aws_config::AWSConfig=global_aws_config()) = appstream("ListAssociatedStacks", Dict{String, Any}("FleetName"=>FleetName); aws_config=aws_config)
list_associated_stacks(FleetName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("ListAssociatedStacks", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("FleetName"=>FleetName), args)); aws_config=aws_config)

"""
    ListTagsForResource()

Retrieves a list of all tags for the specified AppStream 2.0 resource. You can tag AppStream 2.0 image builders, images, fleets, and stacks. For more information about tags, see Tagging Your Resources in the Amazon AppStream 2.0 Administration Guide.

# Required Parameters
- `ResourceArn`: The Amazon Resource Name (ARN) of the resource.

"""

list_tags_for_resource(ResourceArn; aws_config::AWSConfig=global_aws_config()) = appstream("ListTagsForResource", Dict{String, Any}("ResourceArn"=>ResourceArn); aws_config=aws_config)
list_tags_for_resource(ResourceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("ListTagsForResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ResourceArn"=>ResourceArn), args)); aws_config=aws_config)

"""
    StartFleet()

Starts the specified fleet.

# Required Parameters
- `Name`: The name of the fleet.

"""

start_fleet(Name; aws_config::AWSConfig=global_aws_config()) = appstream("StartFleet", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
start_fleet(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("StartFleet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    StartImageBuilder()

Starts the specified image builder.

# Required Parameters
- `Name`: The name of the image builder.

# Optional Parameters
- `AppstreamAgentVersion`: The version of the AppStream 2.0 agent to use for this image builder. To use the latest version of the AppStream 2.0 agent, specify [LATEST].
"""

start_image_builder(Name; aws_config::AWSConfig=global_aws_config()) = appstream("StartImageBuilder", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
start_image_builder(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("StartImageBuilder", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    StopFleet()

Stops the specified fleet.

# Required Parameters
- `Name`: The name of the fleet.

"""

stop_fleet(Name; aws_config::AWSConfig=global_aws_config()) = appstream("StopFleet", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
stop_fleet(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("StopFleet", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    StopImageBuilder()

Stops the specified image builder.

# Required Parameters
- `Name`: The name of the image builder.

"""

stop_image_builder(Name; aws_config::AWSConfig=global_aws_config()) = appstream("StopImageBuilder", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
stop_image_builder(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("StopImageBuilder", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)

"""
    TagResource()

Adds or overwrites one or more tags for the specified AppStream 2.0 resource. You can tag AppStream 2.0 image builders, images, fleets, and stacks. Each tag consists of a key and an optional value. If a resource already has a tag with the same key, this operation updates its value. To list the current tags for your resources, use ListTagsForResource. To disassociate tags from your resources, use UntagResource. For more information about tags, see Tagging Your Resources in the Amazon AppStream 2.0 Administration Guide.

# Required Parameters
- `ResourceArn`: The Amazon Resource Name (ARN) of the resource.
- `Tags`: The tags to associate. A tag is a key-value pair, and the value is optional. For example, Environment=Test. If you do not specify a value, Environment=.  If you do not specify a value, the value is set to an empty string. Generally allowed characters are: letters, numbers, and spaces representable in UTF-8, and the following special characters:  _ . : / = +  - @

"""

tag_resource(ResourceArn, Tags; aws_config::AWSConfig=global_aws_config()) = appstream("TagResource", Dict{String, Any}("ResourceArn"=>ResourceArn, "Tags"=>Tags); aws_config=aws_config)
tag_resource(ResourceArn, Tags, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("TagResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ResourceArn"=>ResourceArn, "Tags"=>Tags), args)); aws_config=aws_config)

"""
    UntagResource()

Disassociates one or more specified tags from the specified AppStream 2.0 resource. To list the current tags for your resources, use ListTagsForResource. For more information about tags, see Tagging Your Resources in the Amazon AppStream 2.0 Administration Guide.

# Required Parameters
- `ResourceArn`: The Amazon Resource Name (ARN) of the resource.
- `TagKeys`: The tag keys for the tags to disassociate.

"""

untag_resource(ResourceArn, TagKeys; aws_config::AWSConfig=global_aws_config()) = appstream("UntagResource", Dict{String, Any}("ResourceArn"=>ResourceArn, "TagKeys"=>TagKeys); aws_config=aws_config)
untag_resource(ResourceArn, TagKeys, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("UntagResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ResourceArn"=>ResourceArn, "TagKeys"=>TagKeys), args)); aws_config=aws_config)

"""
    UpdateDirectoryConfig()

Updates the specified Directory Config object in AppStream 2.0. This object includes the configuration information required to join fleets and image builders to Microsoft Active Directory domains.

# Required Parameters
- `DirectoryName`: The name of the Directory Config object.

# Optional Parameters
- `OrganizationalUnitDistinguishedNames`: The distinguished names of the organizational units for computer accounts.
- `ServiceAccountCredentials`: The credentials for the service account used by the fleet or image builder to connect to the directory.
"""

update_directory_config(DirectoryName; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateDirectoryConfig", Dict{String, Any}("DirectoryName"=>DirectoryName); aws_config=aws_config)
update_directory_config(DirectoryName, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateDirectoryConfig", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DirectoryName"=>DirectoryName), args)); aws_config=aws_config)

"""
    UpdateFleet()

Updates the specified fleet. If the fleet is in the STOPPED state, you can update any attribute except the fleet name. If the fleet is in the RUNNING state, you can update the DisplayName, ComputeCapacity, ImageARN, ImageName, IdleDisconnectTimeoutInSeconds, and DisconnectTimeoutInSeconds attributes. If the fleet is in the STARTING or STOPPING state, you can't update it.

# Optional Parameters
- `AttributesToDelete`: The fleet attributes to delete.
- `ComputeCapacity`: The desired capacity for the fleet.
- `DeleteVpcConfig`: Deletes the VPC association for the specified fleet.
- `Description`: The description to display.
- `DisconnectTimeoutInSeconds`: The amount of time that a streaming session remains active after users disconnect. If users try to reconnect to the streaming session after a disconnection or network interruption within this time interval, they are connected to their previous session. Otherwise, they are connected to a new session with a new streaming instance.  Specify a value between 60 and 360000.
- `DisplayName`: The fleet name to display.
- `DomainJoinInfo`: The name of the directory and organizational unit (OU) to use to join the fleet to a Microsoft Active Directory domain.
- `EnableDefaultInternetAccess`: Enables or disables default internet access for the fleet.
- `IamRoleArn`: The Amazon Resource Name (ARN) of the IAM role to apply to the fleet. To assume a role, a fleet instance calls the AWS Security Token Service (STS) AssumeRole API operation and passes the ARN of the role to use. The operation creates a new session with temporary credentials. AppStream 2.0 retrieves the temporary credentials and creates the appstream_machine_role credential profile on the instance. For more information, see Using an IAM Role to Grant Permissions to Applications and Scripts Running on AppStream 2.0 Streaming Instances in the Amazon AppStream 2.0 Administration Guide.
- `IdleDisconnectTimeoutInSeconds`: The amount of time that users can be idle (inactive) before they are disconnected from their streaming session and the DisconnectTimeoutInSeconds time interval begins. Users are notified before they are disconnected due to inactivity. If users try to reconnect to the streaming session before the time interval specified in DisconnectTimeoutInSeconds elapses, they are connected to their previous session. Users are considered idle when they stop providing keyboard or mouse input during their streaming session. File uploads and downloads, audio in, audio out, and pixels changing do not qualify as user activity. If users continue to be idle after the time interval in IdleDisconnectTimeoutInSeconds elapses, they are disconnected.  To prevent users from being disconnected due to inactivity, specify a value of 0. Otherwise, specify a value between 60 and 3600. The default value is 0.  If you enable this feature, we recommend that you specify a value that corresponds exactly to a whole number of minutes (for example, 60, 120, and 180). If you don't do this, the value is rounded to the nearest minute. For example, if you specify a value of 70, users are disconnected after 1 minute of inactivity. If you specify a value that is at the midpoint between two different minutes, the value is rounded up. For example, if you specify a value of 90, users are disconnected after 2 minutes of inactivity.
- `ImageArn`: The ARN of the public, private, or shared image to use.
- `ImageName`: The name of the image used to create the fleet.
- `InstanceType`: The instance type to use when launching fleet instances. The following instance types are available:   stream.standard.medium   stream.standard.large   stream.compute.large   stream.compute.xlarge   stream.compute.2xlarge   stream.compute.4xlarge   stream.compute.8xlarge   stream.memory.large   stream.memory.xlarge   stream.memory.2xlarge   stream.memory.4xlarge   stream.memory.8xlarge   stream.memory.z1d.large   stream.memory.z1d.xlarge   stream.memory.z1d.2xlarge   stream.memory.z1d.3xlarge   stream.memory.z1d.6xlarge   stream.memory.z1d.12xlarge   stream.graphics-design.large   stream.graphics-design.xlarge   stream.graphics-design.2xlarge   stream.graphics-design.4xlarge   stream.graphics-desktop.2xlarge   stream.graphics.g4dn.xlarge   stream.graphics.g4dn.2xlarge   stream.graphics.g4dn.4xlarge   stream.graphics.g4dn.8xlarge   stream.graphics.g4dn.12xlarge   stream.graphics.g4dn.16xlarge   stream.graphics-pro.4xlarge   stream.graphics-pro.8xlarge   stream.graphics-pro.16xlarge
- `MaxUserDurationInSeconds`: The maximum amount of time that a streaming session can remain active, in seconds. If users are still connected to a streaming instance five minutes before this limit is reached, they are prompted to save any open documents before being disconnected. After this time elapses, the instance is terminated and replaced by a new instance. Specify a value between 600 and 360000.
- `Name`: A unique name for the fleet.
- `StreamView`: The AppStream 2.0 view that is displayed to your users when they stream from the fleet. When APP is specified, only the windows of applications opened by users display. When DESKTOP is specified, the standard desktop that is provided by the operating system displays. The default value is APP.
- `VpcConfig`: The VPC configuration for the fleet.
"""

update_fleet(; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateFleet"; aws_config=aws_config)
update_fleet(args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateFleet", args; aws_config=aws_config)

"""
    UpdateImagePermissions()

Adds or updates permissions for the specified private image.

# Required Parameters
- `ImagePermissions`: The permissions for the image.
- `Name`: The name of the private image.
- `SharedAccountId`: The 12-digit identifier of the AWS account for which you want add or update image permissions.

"""

update_image_permissions(ImagePermissions, Name, SharedAccountId; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateImagePermissions", Dict{String, Any}("ImagePermissions"=>ImagePermissions, "Name"=>Name, "SharedAccountId"=>SharedAccountId); aws_config=aws_config)
update_image_permissions(ImagePermissions, Name, SharedAccountId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateImagePermissions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ImagePermissions"=>ImagePermissions, "Name"=>Name, "SharedAccountId"=>SharedAccountId), args)); aws_config=aws_config)

"""
    UpdateStack()

Updates the specified fields for the specified stack.

# Required Parameters
- `Name`: The name of the stack.

# Optional Parameters
- `AccessEndpoints`: The list of interface VPC endpoint (interface endpoint) objects. Users of the stack can connect to AppStream 2.0 only through the specified endpoints.
- `ApplicationSettings`: The persistent application settings for users of a stack. When these settings are enabled, changes that users make to applications and Windows settings are automatically saved after each session and applied to the next session.
- `AttributesToDelete`: The stack attributes to delete.
- `DeleteStorageConnectors`: Deletes the storage connectors currently enabled for the stack.
- `Description`: The description to display.
- `DisplayName`: The stack name to display.
- `EmbedHostDomains`: The domains where AppStream 2.0 streaming sessions can be embedded in an iframe. You must approve the domains that you want to host embedded AppStream 2.0 streaming sessions.
- `FeedbackURL`: The URL that users are redirected to after they choose the Send Feedback link. If no URL is specified, no Send Feedback link is displayed.
- `RedirectURL`: The URL that users are redirected to after their streaming session ends.
- `StorageConnectors`: The storage connectors to enable.
- `UserSettings`: The actions that are enabled or disabled for users during their streaming sessions. By default, these actions are enabled.
"""

update_stack(Name; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateStack", Dict{String, Any}("Name"=>Name); aws_config=aws_config)
update_stack(Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = appstream("UpdateStack", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name), args)); aws_config=aws_config)


text:
using Tables

struct Query{rows, NT, T}
    stmt::Ptr{Cvoid}
    status::Base.RefValue{Int}
    columns::T
    rowsfetched::Base.RefValue{ODBC.API.SQLLEN}
    boundcols::Vector{Any}
    indcols::Vector{Vector{ODBC.API.SQLLEN}}
    sizes::Vector{ODBC.API.SQLULEN}
    ctypes::Vector{ODBC.API.SQLSMALLINT}
    jltypes::Vector{Type}
end
getstmt(q::Query) = q.stmt

Tables.istable(::Type{<:Query}) = true
Tables.rowaccess(::Type{<:Query}) = true
Tables.rows(q::Query) = q
Tables.schema(q::Query{rows, NT}) where {rows, NT} = Tables.Schema(NT)
Base.IteratorSize(::Type{Query{missing, NT, T}}) where {NT, T} = Base.SizeUnknown()
Base.IteratorSize(::Type{<:Query}) = Base.HasLength()
Base.length(q::Query{rows}) where {rows} = rows
Base.eltype(q::Query{rows, NT}) where {rows, NT} = NT

@inline function generate_namedtuple(::Type{NamedTuple{names, types}}, q, row) where {names, types}
    if @generated
        return Expr(:new, :(NamedTuple{names,$types}), Any[ :(q.columns[$i][row]) for i in 1:length(names) ]...)
    else
        return NamedTuple{names, types}(Tuple(q.columns[i][row] for i = 1:length(names)))
    end
end

function Base.iterate(q::Query{rows, NT}, st=1) where {rows, NT}
    ((st > q.rowsfetched[] && q.status[] != API.SQL_SUCCESS && q.status[] != API.SQL_SUCCESS_WITH_INFO) || q.status[] == API.SQL_NO_DATA) && return nothing
    nt = generate_namedtuple(NT, q, st)
    if st == q.rowsfetched[]
        q.status[] = API.SQLFetchScroll(q.stmt, API.SQL_FETCH_NEXT, 0)
        q.rowsfetched[] > 0 && foreach(i->cast!(q.jltypes[i], q, i), 1:length(q.jltypes))
        st = 0
    end
    return nt, st + 1
end

function Query(dsn::DSN, query::AbstractString)
    stmt = dsn.stmt_ptr
    ODBCFreeStmt!(stmt)
    @CHECK stmt API.SQL_HANDLE_STMT API.SQLExecDirect(stmt, query)
    rowsref, colsref = Ref{Int}(), Ref{Int16}()
    API.SQLNumResultCols(stmt, colsref)
    API.SQLRowCount(stmt, rowsref)
    rows, cols = rowsref[], colsref[]
    # Allocate arrays to hold each column's metadata
    cnames = Vector{Symbol}(undef, cols)
    ctypes, csizes = Vector{API.SQLSMALLINT}(undef, cols), Vector{API.SQLULEN}(undef, cols)
    cdigits, cnulls = Vector{API.SQLSMALLINT}(undef, cols), Vector{API.SQLSMALLINT}(undef, cols)
    juliatypes = Vector{Type}(undef, cols)
    alloctypes = Vector{DataType}(undef, cols)
    longtexts = Vector{Bool}(undef, cols)
    longtext = false
    # Allocate space for and fetch the name, type, size, etc. for each column
    len, dt, csize = Ref{API.SQLSMALLINT}(), Ref{API.SQLSMALLINT}(), Ref{API.SQLULEN}()
    digits, maybemissing = Ref{API.SQLSMALLINT}(), Ref{API.SQLSMALLINT}()
    cname = Block(API.SQLWCHAR, BUFLEN)
    for x = 1:cols
        API.SQLDescribeCol(stmt, x, cname.ptr, BUFLEN, len, dt, csize, digits, maybemissing)
        cnames[x] = Symbol(string(cname, len[]))
        t = dt[]
        ctypes[x], csizes[x], cdigits[x], cnulls[x] = t, csize[], digits[], maybemissing[]
        alloctypes[x], juliatypes[x], longtexts[x] = API.SQL2Julia[t]
        longtext |= longtexts[x]
    end
    # Determine fetch strategy
    # rows might be -1 (dbms doesn't return total rows in resultset), 0 (empty resultset), or 1+
    if longtext
        rowset = allocsize = 1
    elseif rows > -1
        # rowset = min(rows, API.MAXFETCHSIZE)
        allocsize = rowset = rows
    else
        rowset = allocsize = 1
    end
    API.SQLSetStmtAttr(stmt, API.SQL_ATTR_ROW_ARRAY_SIZE, rowset, API.SQL_IS_UINTEGER)
    boundcols = Vector{Any}(undef, cols)
    indcols = Vector{Vector{API.SQLLEN}}(undef, cols)
    for x = 1:cols
        if longtexts[x]
            boundcols[x], indcols[x] = alloctypes[x][], API.SQLLEN[]
        else
            boundcols[x], elsize = internal_allocate(alloctypes[x], rowset, csizes[x])
            indcols[x] = Vector{API.SQLLEN}(undef, rowset)
            API.SQLBindCols(stmt, x, API.SQL2C[ctypes[x]], pointer(boundcols[x]), elsize, indcols[x])
        end
    end
    names = Tuple(cnames)
    columns = Tuple(allocate(T) for T in juliatypes)
    NT = NamedTuple{names, Tuple{juliatypes...}}
    rowsfetched = Ref{API.SQLLEN}(0) # will be populated by call to SQLFetchScroll
    API.SQLSetStmtAttr(stmt, API.SQL_ATTR_ROWS_FETCHED_PTR, rowsfetched, API.SQL_NTS)
    types = [API.SQL2C[ctypes[x]] for x = 1:cols]
    jltypes = Type[longtexts[x] ? API.Long{T} : T for (x, T) in enumerate(juliatypes)]
    q = Query{rows >= 0 ? rows : missing, NT, typeof(columns)}(stmt, Ref(0), columns, rowsfetched, boundcols, indcols, csizes, types, jltypes)
    if rows != 0
        q.status[] = Int(API.SQLFetchScroll(q.stmt, API.SQL_FETCH_NEXT, 0))
        q.rowsfetched[] > 0 && foreach(i->cast!(jltypes[i], q, i), 1:length(jltypes))
    else
        q.status[] = 100
    end
    return q
end

cast(x) = x
cast(x::Dates.Date) = API.SQLDate(x)
cast(x::Dates.DateTime) = API.SQLTimestamp(x)
cast(x::String) = WeakRefString(pointer(x), sizeof(x))

getpointer(::Type{T}, A, i) where {T} = unsafe_load(Ptr{Ptr{Cvoid}}(pointer(A, i)))
getpointer(::Type{WeakRefString{T}}, A, i) where {T} = convert(Ptr{Cvoid}, A[i].ptr)
getpointer(::Type{String}, A, i) = convert(Ptr{Cvoid}, pointer(Vector{UInt8}(A[i])))

sqllength(x) = 1
sqllength(x::AbstractString) = length(x)
sqllength(x::Vector{UInt8}) = length(x)
sqllength(x::WeakRefString) = x.len
sqllength(x::API.SQLDate) = 10
sqllength(x::Union{API.SQLTime,API.SQLTimestamp}) = length(string(x))

clength(x) = 1
clength(x::AbstractString) = length(x)
clength(x::Vector{UInt8}) = length(x)
clength(x::WeakRefString{T}) where {T} = codeunits2bytes(T, x.len)
clength(x::CategoricalArrays.CategoricalValue) = length(String(x))
clength(x::Missing) = API.SQL_NULL_DATA

digits(x) = 0
digits(x::API.SQLTimestamp) = length(string(x.fraction * 1000000))

# primitive types
allocate(::Type{T}) where {T} = Vector{T}(undef, 0)
allocate(::Type{Union{Missing, WeakRefString{T}}}) where {T} = WeakRefStringArray(UInt8[], Union{Missing, WeakRefString{T}}, 0)

internal_allocate(::Type{T}, rowset, size) where {T} = Vector{T}(undef, rowset), sizeof(T)
# string/binary types
internal_allocate(::Type{T}, rowset, size) where {T <: Union{UInt8, UInt16, UInt32}} = zeros(T, rowset * (size + 1)), sizeof(T) * (size + 1)

# primitive types
function cast!(::Type{T}, source, col) where {T}
    len = source.rowsfetched[]
    c = source.columns[col]
    resize!(c, len)
    ind = source.indcols[col]
    data = source.boundcols[col]
    @simd for i = 1:len
        @inbounds c[i] = ifelse(ind[i] == API.SQL_NULL_DATA, missing, data[i])
    end
    return c
end

cast(::Type{Dec64}, arr, cur, ind) = ind <= 0 ? Dec64(0) : parse(Dec64, String(unsafe_wrap(Array, pointer(arr, cur), ind)))

function cast!(::Type{Union{Dec64, Missing}}, source, col)
    len = source.rowsfetched[]
    c = source.columns[col]
    resize!(c, len)
    cur = 1
    elsize = source.sizes[col] + 1
    inds = source.indcols[col]
    @inbounds for i = 1:len
        ind = inds[i]
        c[i] = ind == API.SQL_NULL_DATA ? missing : cast(Dec64, source.boundcols[col], cur, ind)
        cur += elsize
    end
    return c
end

cast(::Type{Vector{UInt8}}, arr, cur, ind) = arr[cur:(cur + max(ind, 0) - 1)]

function cast!(::Type{Union{Vector{UInt8}, Missing}}, source, col)
    len = source.rowsfetched[]
    c = source.columns[col]
    resize!(c, len)
    cur = 1
    elsize = source.sizes[col] + 1
    inds = source.indcols[col]
    @inbounds for i = 1:len
        ind = inds[i]
        c[i] = ind == API.SQL_NULL_DATA ? missing : cast(Vector{UInt8}, source.boundcols[col], cur, ind)
        cur += elsize
    end
    return c
end

# string types
bytes2codeunits(::Type{UInt8},  bytes) = ifelse(bytes == API.SQL_NULL_DATA, 0, Int(bytes))
bytes2codeunits(::Type{UInt16}, bytes) = ifelse(bytes == API.SQL_NULL_DATA, 0, Int(bytes >> 1))
bytes2codeunits(::Type{UInt32}, bytes) = ifelse(bytes == API.SQL_NULL_DATA, 0, Int(bytes >> 2))
codeunits2bytes(::Type{UInt8},  bytes) = ifelse(bytes == API.SQL_NULL_DATA, 0, Int(bytes))
codeunits2bytes(::Type{UInt16}, bytes) = ifelse(bytes == API.SQL_NULL_DATA, 0, Int(bytes * 2))
codeunits2bytes(::Type{UInt32}, bytes) = ifelse(bytes == API.SQL_NULL_DATA, 0, Int(bytes * 4))

function cast!(::Type{Union{String, Missing}}, source, col)
    len = source.rowsfetched[]
    c = source.columns[col]
    resize!(c, len)
    data = source.boundcols[col]
    T = eltype(data)
    cur = 1
    elsize = source.sizes[col] + 1
    inds = source.indcols[col]
    @inbounds for i in 1:len
        ind = inds[i]
        length = bytes2codeunits(T, max(ind, 0))
        c[i] = ind == API.SQL_NULL_DATA ? missing : (length == 0 ? "" : transcode(String, data[cur:(cur + length - 1)]))
        cur += elsize
    end
    return c
end

function cast!(::Type{Union{WeakRefString{T}, Missing}}, source, col) where {T}
    len = source.rowsfetched[]
    c = source.columns[col]
    resize!(c, len)
    empty!(c.data)
    data = copy(source.boundcols[col])
    push!(c.data, data)
    cur = 1
    elsize = source.sizes[col] + 1
    inds = source.indcols[col]
    EMPTY = WeakRefString{T}(Ptr{T}(0), 0)
    @inbounds for i = 1:len
        ind = inds[i]
        length = bytes2codeunits(T, max(ind, 0))
        c[i] = ind == API.SQL_NULL_DATA ? missing : (length == 0 ? EMPTY : WeakRefString{T}(pointer(data, cur), length))
        cur += elsize
    end
    return c
end

# long types
const LONG_DATA_BUFFER_SIZE = 1024

function cast!(::Type{API.Long{Union{T, Missing}}}, source, col) where {T}
    stmt = getstmt(source)
    eT = eltype(source.boundcols[col])
    data = eT[]
    buf = zeros(eT, LONG_DATA_BUFFER_SIZE)
    ind = Ref{API.SQLLEN}()
    res = API.SQLGetData(stmt, col, source.ctypes[col], pointer(buf), sizeof(buf), ind)
    isnull = ind[] == API.SQL_NULL_DATA
    while !isnull
        len = ind[]
        oldlen = length(data)
        resize!(data, oldlen + bytes2codeunits(eT, len))
        ccall(:memcpy, Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), pointer(data, oldlen + 1), pointer(buf), len)
        res = API.SQLGetData(stmt, col, source.ctypes[col], pointer(buf), length(buf), ind)
        res != API.SQL_SUCCESS && res != API.SQL_SUCCESS_WITH_INFO && break
    end
    c = source.columns[col]
    resize!(c, 1)
    c[1] = isnull ? missing : T(transcode(UInt8, data))
    return c
end

function query(dsn::DSN, sql::AbstractString, sink=DataFrame, args...; weakrefstrings::Bool=true, append::Bool=false, transforms::Dict=Dict{Int,Function}())
    if append
        Base.depwarn("`ODBC.query(dsn, sql; append=true)` is no longer supported in favor of individual sink support, like `append!(existing_dataframe, ODBC.query(dsn, sql))`", nothing)
    end
    !weakrefstrings && Base.depwarn("`ODBC.query(dsn, sql; weakrefstrings=false)` is no longer supported", nothing)
    !isempty(transforms) && Base.depwarn("`ODBC.query(dsn, sql; transforms=...)` is no longer supported", nothing)
    return DataFrame(ODBC.Query(dsn, sql))
end

function query(dsn::DSN, sql::AbstractString, sink::T; weakrefstrings::Bool=true, append::Bool=false, transforms::Dict=Dict{Int,Function}()) where {T}
    if append
        Base.depwarn("`ODBC.query(dsn, sql; append=true)` is no longer supported in favor of individual sink support, like `append!(existing_dataframe, ODBC.query(dsn, sql))`", nothing)
    end
    !weakrefstrings && Base.depwarn("`ODBC.query(dsn, sql; weakrefstrings=false)` is no longer supported", nothing)
    !isempty(transforms) && Base.depwarn("`ODBC.query(dsn, sql; transforms=...)` is no longer supported", nothing)
    return DataFrame(ODBC.Query(dsn, sql))
end

function query(source::Query, sink=DataFrame, args...; append::Bool=false, transforms::Dict=Dict{Int,Function}())
    if append
        Base.depwarn("`ODBC.query(dsn, sql; append=true)` is no longer supported in favor of individual sink support, like `append!(existing_dataframe, ODBC.query(dsn, sql))`", nothing)
    end
    if sink != DataFrame
        Base.depwarn("`ODBC.query(dsn, sql, $(typeof(sink)))` is no longer supported; returning a DataFrame instead", nothing)
    end
    !isempty(transforms) && Base.depwarn("`ODBC.query(dsn, sql; transforms=...)` is no longer supported", nothing)
    return DataFrame(source)
end
function query(source::Query, sink::T; append::Bool=false, transforms::Dict=Dict{Int,Function}()) where {T}
    if append
        Base.depwarn("`ODBC.query(dsn, sql; append=true)` is no longer supported in favor of individual sink support, like `append!(existing_dataframe, ODBC.query(dsn, sql))`", nothing)
    end
    !isempty(transforms) && Base.depwarn("`ODBC.query(dsn, sql; transforms=...)` is no longer supported", nothing)
    return DataFrame(source)
end

"Convenience string macro for executing an SQL statement against a DSN."
macro sql_str(s,dsn)
    query(dsn,s)
end

function Source(dsn::DSN, query::AbstractString; weakrefstrings::Bool=true, noquery::Bool=false)
    Base.depwarn("`ODBC.Source(dsn, query)` is deprecated in favor of `ODBC.Query(dsn, query)`", nothing)
    return Query(dsn, query)
end

ext: jl


text:
const EQ{T} = MOI.ConstraintIndex{MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}}

"""
Let `H = HermitianToSymmetricPSDBridge(n)`, `S = PositiveSemidefiniteConeTriangle(2n)`
and `P = S ∩ con_11_22 ∩ con_12_21 ∩ con12diag`.
Suppose for simplicity that the elements of P are ordered as:
```
\\ 1 |\\ 2
 \\  | 3
  \\ |4_\\
   \\  5
    \\
     \\
```
We have `P = A * H` where
```
    [I  0]
    [0  I]
A = [0  0]
    [0 -I]
    [I  0]
```
Therefore, `H* = A* * P*` where
```
     [I 0 0  0 I]
A* = [0 I 0 -I 0]
```
Moreover, as `(S ∩ T)* = S* + T*` for cones `S` and `T`, we have
```
P* = S* + con_11_22* + con_12_21* + con12diag*
```
the dual vector of `P*` is the dual vector of `S*` for which we add in the corresponding
entries the dual of the three constraints, multiplied by the coefficients for the `EqualTo` constraints.
Note that these contribution cancel out when we multiply them by `A*`:
A* * (S* + con_11_22* + con_12_21* + con12diag*) = A* * S*
so we can just ignore them.
"""
struct HermitianToSymmetricPSDBridge{T} <: MOIB.Variable.AbstractBridge
    variables::Vector{MOI.VariableIndex}
    psd_constraint::MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle}
    con_11_22::Vector{EQ{T}}
    con12diag::Vector{EQ{T}}
    con_12_21::Vector{EQ{T}}
end

function MOIB.Variable.bridge_constrained_variable(
    ::Type{HermitianToSymmetricPSDBridge{T}}, model::MOI.ModelLike,
    set::COI.HermitianPositiveSemidefiniteConeTriangle) where T

    n = set.side_dimension
    variables, psd_constraint = MOI.add_constrained_variables(model, MOI.PositiveSemidefiniteConeTriangle(2n))

    k11 = 0
    k12 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(n))
    k21 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(2n)) + 1
    k22 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(n))
    X11() = variables[k11]
    X12() = variables[k12]
    function X21(i, j)
        I = j
        J = n + i
        k21 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(J - 1)) + I
        return variables[k21]
    end
    X22() = variables[k22]
    con_11_22 = EQ{T}[]
    con12diag = EQ{T}[]
    con_12_21 = EQ{T}[]
    for j in 1:n
        k22 += n
        for i in 1:j
            k11 += 1
            k12 += 1
            k22 += 1
            push!(con_11_22, MOI.add_constraint(model, MOI.Utilities.operate(-, T, X11(), X22()), MOI.EqualTo(zero(T))))
            if i == j
                push!(con12diag, MOI.add_constraint(model, convert(MOI.ScalarAffineFunction{T}, X12()), MOI.EqualTo(zero(T))))
            else
                push!(con_12_21, MOI.add_constraint(model, MOI.Utilities.operate(+, T, X21(i, j), X12()), MOI.EqualTo(zero(T))))
            end
        end
        k12 += n
    end

    return HermitianToSymmetricPSDBridge(variables, psd_constraint, con_11_22, con12diag, con_12_21)
end

function MOIB.Variable.supports_constrained_variable(
    ::Type{<:HermitianToSymmetricPSDBridge}, ::Type{COI.HermitianPositiveSemidefiniteConeTriangle})
    return true
end
function MOIB.added_constrained_variable_types(::Type{<:HermitianToSymmetricPSDBridge})
    return [(MOI.PositiveSemidefiniteConeTriangle,)]
end
function MOIB.added_constraint_types(::Type{HermitianToSymmetricPSDBridge{T}}) where T
    return [(MOI.ScalarAffineFunction{T}, MOI.EqualTo{T})]
end

# Attributes, Bridge acting as a model
function MOI.get(bridge::HermitianToSymmetricPSDBridge, ::MOI.NumberOfVariables)
    return length(bridge.variables)
end
function MOI.get(bridge::HermitianToSymmetricPSDBridge, ::MOI.ListOfVariableIndices)
    return bridge.variables
end
function MOI.get(bridge::HermitianToSymmetricPSDBridge,
                 ::MOI.NumberOfConstraints{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle})
    return 1
end
function MOI.get(bridge::HermitianToSymmetricPSDBridge,
                 ::MOI.ListOfConstraintIndices{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeTriangle})
    return [bridge.psd_constraint]
end
function MOI.get(bridge::HermitianToSymmetricPSDBridge{T},
                 ::MOI.NumberOfConstraints{MOI.ScalarAffineFunction{T},
                                           MOI.EqualTo{T}}) where T
    return length(bridge.con_11_22) + length(bridge.con12diag) + length(bridge.con_12_21)
end
function MOI.get(bridge::HermitianToSymmetricPSDBridge{T},
                 ::MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{T},
                                               MOI.EqualTo{T}}) where T
    return [bridge.con_11_22; bridge.con12diag; bridge.con_12_21]
end

# References
function MOI.delete(model::MOI.ModelLike, bridge::HermitianToSymmetricPSDBridge)
    for ci in bridge.con_11_22
        MOI.delete(model, ci)
    end
    for ci in bridge.con12diag
        MOI.delete(model, ci)
    end
    for ci in bridge.con_12_21
        MOI.delete(model, ci)
    end
    MOI.delete(model, bridge.variables)
end

# Attributes, Bridge acting as a constraint

function MOI.get(model::MOI.ModelLike, ::MOI.ConstraintSet,
                 bridge::HermitianToSymmetricPSDBridge)
    return COI.HermitianPositiveSemidefiniteConeTriangle(length(bridge.con12diag))
end

function _matrix_indices(k)
    # If `k` is a diagonal index, `s(k)` is odd and 1 + 8k is a perfect square.
    n = 1 + 8k
    s = isqrt(n)
    if s^2 == n
        j = div(s, 2)
    else
        # Otherwise, if it is after the diagonal index `k` but before the diagonal
        # index `k'` with `s(k') = s(k) + 2`, we have `s(k) <= s < s(k) + 2`.
        # By shifting by `+1` before `div`, we make sure to have the right column.
        j = div(s + 1, 2)
    end
    i = k - MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(j - 1))
    return i, j
end

function _variable_map(idx::MOIB.IndexInVector, n)
    N = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(n))
    if idx.value <= N
        return idx.value
    else
        i, j = _matrix_indices(idx.value - N)
        return N + j * n + MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(j)) + i
    end
end
function _variable(bridge::HermitianToSymmetricPSDBridge, i::MOIB.IndexInVector)
    return bridge.variables[_variable_map(i, length(bridge.con12diag))]
end

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
                 bridge::HermitianToSymmetricPSDBridge{T}) where T
    values = MOI.get(model, attr, bridge.psd_constraint)
    M = MOI.dimension(MOI.get(model, MOI.ConstraintSet(), bridge))
    n = length(bridge.con12diag)
    return [values[_variable_map(MOIB.IndexInVector(i), n)] for i in 1:M]
end

# See docstring of bridge for why we ignore the dual of the constraints
# `con_11_22`, `con_12_21` and `con12diag`.
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual,
                 bridge::HermitianToSymmetricPSDBridge{T}) where T
    dual = MOI.get(model, attr, bridge.psd_constraint)
    M = MOI.dimension(MOI.get(model, MOI.ConstraintSet(), bridge))
    mapped = zeros(T, M)
    n = length(bridge.con12diag)
    N = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(n))
    k11 = 0
    k12 = N
    k21 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(2n)) + 1
    k22 = N
    k = 0
    for j in 1:n
        k21 -= n + 1 - j
        k22 += n
        for i in 1:j
            k11 += 1
            k12 += 1
            k21 -= 1
            k22 += 1
            mapped[k11] += dual[k11]
            mapped[k11] += dual[k22]
            if i != j
                k += 1
                mapped[N + k] += dual[k12]
                mapped[N + k] -= dual[k21]
            end
        end
        k12 += n
        k21 -= n - j
    end
    return mapped
end

function MOI.get(model::MOI.ModelLike, attr::MOI.VariablePrimal,
                 bridge::HermitianToSymmetricPSDBridge{T}, i::MOIB.IndexInVector) where T
    value = MOI.get(model, attr, _variable(bridge, i))
end

function MOIB.bridged_function(bridge::HermitianToSymmetricPSDBridge{T}, i::MOIB.IndexInVector) where T
    func = _variable(bridge, i)
    return convert(MOI.ScalarAffineFunction{T}, func)
end
function MOIB.Variable.unbridged_map(bridge::HermitianToSymmetricPSDBridge{T}, vi::MOI.VariableIndex,
                       i::MOIB.IndexInVector) where T
    func = convert(MOI.ScalarAffineFunction{T}, vi)
    return (_variable(bridge, i) => func,)
end