"""
Autogenerated state module using `pop-create-idem <https://gitlab.com/saltstack/pop/pop-create-idem>`__

hub.exec.boto3.client.opsworks.create_layer
hub.exec.boto3.client.opsworks.delete_layer
hub.exec.boto3.client.opsworks.describe_layers
hub.exec.boto3.client.opsworks.update_layer
resource = hub.tool.boto3.resource.create(ctx, "opsworks", "Layer", name)
hub.tool.boto3.resource.exec(resource, delete, *args, **kwargs)
"""



from typing import *
import dict_tools.differ as differ
async def present(hub, ctx, name: Text, stack_id: Text, type_: Text, shortname: Text, attributes: Dict = None, cloud_watch_logs_configuration: Dict = None, custom_instance_profile_arn: Text = None, custom_json: Text = None, custom_security_group_ids: List = None, packages: List = None, volume_configurations: List = None, enable_auto_healing: bool = None, auto_assign_elastic_ips: bool = None, auto_assign_public_ips: bool = None, custom_recipes: Dict = None, install_updates_on_boot: bool = None, use_ebs_optimized_instances: bool = None, lifecycle_event_configuration: Dict = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Creates a layer. For more information, see How to Create a Layer.  You should use CreateLayer for noncustom
    layer types such as PHP App Server only if the stack does not have an existing layer of that type. A stack can
    have at most one instance of each noncustom layer; if you attempt to create a second instance, CreateLayer
    fails. A stack can have an arbitrary number of custom layers, so you can call CreateLayer as many times as you
    like for that layer type.   Required Permissions: To use this action, an IAM user must have a Manage permissions
    level for the stack, or an attached policy that explicitly grants permissions. For more information on user
    permissions, see Managing User Permissions.

    Args:
        name(Text): The layer name, which is used by the console.
        stack_id(Text): The layer stack ID.
        type_(Text): The layer type. A stack cannot have more than one built-in layer of the same type. It can have
            any number of custom layers. Built-in layers are not available in Chef 12 stacks.
        shortname(Text): For custom layers only, use this parameter to specify the layer's short name, which is used
            internally by AWS OpsWorks Stacks and by Chef recipes. The short name is also used as the name
            for the directory where your app files are installed. It can have a maximum of 200 characters,
            which are limited to the alphanumeric characters, '-', '_', and '.'. The built-in layers' short
            names are defined by AWS OpsWorks Stacks. For more information, see the Layer Reference.
        attributes(Dict, optional): One or more user-defined key-value pairs to be added to the stack attributes. To create a
            cluster layer, set the EcsClusterArn attribute to the cluster's ARN. Defaults to None.
        cloud_watch_logs_configuration(Dict, optional): Specifies CloudWatch Logs configuration options for the layer. For more information, see
            CloudWatchLogsLogStream. Defaults to None.
        custom_instance_profile_arn(Text, optional): The ARN of an IAM profile to be used for the layer's EC2 instances. For more information about
            IAM ARNs, see Using Identifiers. Defaults to None.
        custom_json(Text, optional): A JSON-formatted string containing custom stack configuration and deployment attributes to be
            installed on the layer's instances. For more information, see  Using Custom JSON. This feature
            is supported as of version 1.7.42 of the AWS CLI. Defaults to None.
        custom_security_group_ids(List, optional): An array containing the layer custom security group IDs. Defaults to None.
        packages(List, optional): An array of Package objects that describes the layer packages. Defaults to None.
        volume_configurations(List, optional): A VolumeConfigurations object that describes the layer's Amazon EBS volumes. Defaults to None.
        enable_auto_healing(bool, optional): Whether to disable auto healing for the layer. Defaults to None.
        auto_assign_elastic_ips(bool, optional): Whether to automatically assign an Elastic IP address to the layer's instances. For more
            information, see How to Edit a Layer. Defaults to None.
        auto_assign_public_ips(bool, optional): For stacks that are running in a VPC, whether to automatically assign a public IP address to the
            layer's instances. For more information, see How to Edit a Layer. Defaults to None.
        custom_recipes(Dict, optional): A LayerCustomRecipes object that specifies the layer custom recipes. Defaults to None.
        install_updates_on_boot(bool, optional): Whether to install operating system and package updates when the instance boots. The default
            value is true. To control when updates are installed, set this value to false. You must then
            update your instances manually by using CreateDeployment to run the update_dependencies stack
            command or by manually running yum (Amazon Linux) or apt-get (Ubuntu) on the instances.   To
            ensure that your instances have the latest security updates, we strongly recommend using the
            default value of true. Defaults to None.
        use_ebs_optimized_instances(bool, optional): Whether to use Amazon EBS-optimized instances. Defaults to None.
        lifecycle_event_configuration(Dict, optional): A LifeCycleEventConfiguration object that you can use to configure the Shutdown event to specify
            an execution timeout and enable or disable Elastic Load Balancer connection draining. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_present:
              aws_auto.opsworks.layer.present:
                - name: value
                - stack_id: value
                - type_: value
                - shortname: value
    '''
    
    result = dict(comment="", changes= None, name=name, result=True)
    ret = await hub.exec.boto3.client.opsworks.layer.id(
        ctx,
        jmes_path=name
    )
    if ret["status"]:
        # name is now the first id that matched the JMES search path
        name = ret["ret"]
    

    resource = hub.tool.boto3.resource.create(ctx, "opsworks", "Layer", name)
    before = await hub.tool.boto3.resource.describe(resource)

    if before:
        result["comment"] = f"'{name}' already exists"
    else:
        try:
            ret = await hub.exec.boto3.client.opsworks.create_layer(
                ctx,
                
                
                **{"Name": name, "StackId": stack_id, "Type": type_, "Shortname": shortname, "Attributes": attributes, "CloudWatchLogsConfiguration": cloud_watch_logs_configuration, "CustomInstanceProfileArn": custom_instance_profile_arn, "CustomJson": custom_json, "CustomSecurityGroupIds": custom_security_group_ids, "Packages": packages, "VolumeConfigurations": volume_configurations, "EnableAutoHealing": enable_auto_healing, "AutoAssignElasticIps": auto_assign_elastic_ips, "AutoAssignPublicIps": auto_assign_public_ips, "CustomRecipes": custom_recipes, "InstallUpdatesOnBoot": install_updates_on_boot, "UseEbsOptimizedInstances": use_ebs_optimized_instances, "LifecycleEventConfiguration": lifecycle_event_configuration}
            )
            result["result"] = ret["status"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                return result
            ret["comment"] = f"Created '{name}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"

    
    # TODO perform other modifications as needed here
    ...

    after = await hub.tool.boto3.resource.describe(resource)
    result["changes"] = differ.deep_diff(before, after)
    return result

async def absent(hub, ctx, name: Text, layer_id: Text)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Deletes a specified layer. You must first stop and then delete all associated instances or unassign registered
    instances. For more information, see How to Delete a Layer.  Required Permissions: To use this action, an IAM
    user must have a Manage permissions level for the stack, or an attached policy that explicitly grants
    permissions. For more information on user permissions, see Managing User Permissions.

    Args:
        name(Text): A name, ID, or JMES search path to identify the resource.
        layer_id(Text): The layer ID.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_absent:
              aws_auto.opsworks.layer.absent:
                - name: value
                - layer_id: value
    '''
    
    result = dict(comment="", changes= None, name=name, result=True)
    ret = await hub.exec.boto3.client.opsworks.layer.id(
        ctx,
        jmes_path=name
    )
    if ret["status"]:
        # name is now the first id that matched the JMES search path
        name = ret["ret"]
    

    resource = hub.tool.boto3.resource.create(ctx, "opsworks", "Layer", name)

    before = await hub.tool.boto3.resource.describe(resource)

    if not before:
        result["comment"] = f"'{name}' already absent"
    else:
        try:
            ret = await hub.exec.boto3.client.opsworks.delete_layer(
                ctx,
                
                
                **{"LayerId": layer_id}
            )
            result["result"] = ret["status"]
            if not result["result"]:
                result["comment"] = ret["comment"]
                return result
            result["comment"] = f"Deleted '{name}'"
        except hub.tool.boto3.exception.ClientError as e:
            result["comment"] = f"{e.__class__.__name__}: {e}"

    

    after = await hub.tool.boto3.resource.describe(resource)
    result["changes"] = differ.deep_diff(before, after)
    return result

