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

hub.exec.boto3.client.ssm.create_association
hub.exec.boto3.client.ssm.delete_association
hub.exec.boto3.client.ssm.describe_association
hub.exec.boto3.client.ssm.list_associations
hub.exec.boto3.client.ssm.update_association
"""



from typing import *
import dict_tools.differ as differ
async def present(hub, ctx, name: Text, document_version: Text = None, instance_id: Text = None, parameters: Dict = None, targets: List = None, schedule_expression: Text = None, output_location: Dict = None, association_name: Text = None, automation_target_parameter_name: Text = None, max_errors: Text = None, max_concurrency: Text = None, compliance_severity: Text = None, sync_compliance: Text = None, apply_only_at_cron_interval: bool = None, calendar_names: List = None, target_locations: List = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    A State Manager association defines the state that you want to maintain on your instances. For example, an
    association can specify that anti-virus software must be installed and running on your instances, or that
    certain ports must be closed. For static targets, the association specifies a schedule for when the
    configuration is reapplied. For dynamic targets, such as an Amazon Web Services resource group or an Amazon Web
    Services autoscaling group, State Manager, a capability of Amazon Web Services Systems Manager applies the
    configuration when new instances are added to the group. The association also specifies actions to take when
    applying the configuration. For example, an association for anti-virus software might run once a day. If the
    software isn't installed, then State Manager installs it. If the software is installed, but the service isn't
    running, then the association might instruct State Manager to start the service.

    Args:
        name(Text): The name of the SSM Command document or Automation runbook that contains the configuration
            information for the instance. You can specify Amazon Web Services-predefined documents,
            documents you created, or a document that is shared with you from another account. For Systems
            Manager documents (SSM documents) that are shared with you from other Amazon Web Services
            accounts, you must specify the complete SSM document ARN, in the following format:
            arn:partition:ssm:region:account-id:document/document-name   For example:  arn:aws:ssm:us-
            east-2:12345678912:document/My-Shared-Document  For Amazon Web Services-predefined documents and
            SSM documents you created in your account, you only need to specify the document name. For
            example, AWS-ApplyPatchBaseline or My-Document.
        document_version(Text, optional): The document version you want to associate with the target(s). Can be a specific version or the
            default version. Defaults to None.
        instance_id(Text, optional): The instance ID.   InstanceId has been deprecated. To specify an instance ID for an association,
            use the Targets parameter. Requests that include the parameter InstanceID with Systems Manager
            documents (SSM documents) that use schema version 2.0 or later will fail. In addition, if you
            use the parameter InstanceId, you can't use the parameters AssociationName, DocumentVersion,
            MaxErrors, MaxConcurrency, OutputLocation, or ScheduleExpression. To use these parameters, you
            must use the Targets parameter. Defaults to None.
        parameters(Dict, optional): The parameters for the runtime configuration of the document. Defaults to None.
        targets(List, optional): The targets for the association. You can target instances by using tags, Amazon Web Services
            resource groups, all instances in an Amazon Web Services account, or individual instance IDs.
            For more information about choosing targets for an association, see Using targets and rate
            controls with State Manager associations in the Amazon Web Services Systems Manager User Guide. Defaults to None.
        schedule_expression(Text, optional): A cron expression when the association will be applied to the target(s). Defaults to None.
        output_location(Dict, optional): An Amazon Simple Storage Service (Amazon S3) bucket where you want to store the output details
            of the request. Defaults to None.
        association_name(Text, optional): Specify a descriptive name for the association. Defaults to None.
        automation_target_parameter_name(Text, optional): Specify the target for the association. This target is required for associations that use an
            Automation runbook and target resources by using rate controls. Automation is a capability of
            Amazon Web Services Systems Manager. Defaults to None.
        max_errors(Text, optional): The number of errors that are allowed before the system stops sending requests to run the
            association on additional targets. You can specify either an absolute number of errors, for
            example 10, or a percentage of the target set, for example 10%. If you specify 3, for example,
            the system stops sending requests when the fourth error is received. If you specify 0, then the
            system stops sending requests after the first error is returned. If you run an association on 50
            instances and set MaxError to 10%, then the system stops sending the request when the sixth
            error is received. Executions that are already running an association when MaxErrors is reached
            are allowed to complete, but some of these executions may fail as well. If you need to ensure
            that there won't be more than max-errors failed executions, set MaxConcurrency to 1 so that
            executions proceed one at a time. Defaults to None.
        max_concurrency(Text, optional): The maximum number of targets allowed to run the association at the same time. You can specify a
            number, for example 10, or a percentage of the target set, for example 10%. The default value is
            100%, which means all targets run the association at the same time. If a new instance starts and
            attempts to run an association while Systems Manager is running MaxConcurrency associations, the
            association is allowed to run. During the next association interval, the new instance will
            process its association within the limit specified for MaxConcurrency. Defaults to None.
        compliance_severity(Text, optional): The severity level to assign to the association. Defaults to None.
        sync_compliance(Text, optional): The mode for generating association compliance. You can specify AUTO or MANUAL. In AUTO mode,
            the system uses the status of the association execution to determine the compliance status. If
            the association execution runs successfully, then the association is COMPLIANT. If the
            association execution doesn't run successfully, the association is NON-COMPLIANT. In MANUAL
            mode, you must specify the AssociationId as a parameter for the PutComplianceItems API
            operation. In this case, compliance data isn't managed by State Manager. It is managed by your
            direct call to the PutComplianceItems API operation. By default, all associations use AUTO mode. Defaults to None.
        apply_only_at_cron_interval(bool, optional): By default, when you create a new association, the system runs it immediately after it is
            created and then according to the schedule you specified. Specify this option if you don't want
            an association to run immediately after you create it. This parameter isn't supported for rate
            expressions. Defaults to None.
        calendar_names(List, optional): The names or Amazon Resource Names (ARNs) of the Change Calendar type documents you want to gate
            your associations under. The associations only run when that change calendar is open. For more
            information, see Amazon Web Services Systems Manager Change Calendar. Defaults to None.
        target_locations(List, optional): A location is a combination of Amazon Web Services Regions and Amazon Web Services accounts
            where you want to run the association. Use this action to create an association in multiple
            Regions and multiple accounts. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

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

    
    before = await hub.exec.boto3.client.ssm.describe_association(name)

    if before:
        result["comment"] = f"'{name}' already exists"
    else:
        try:
            ret = await hub.exec.boto3.client.ssm.create_association(
                ctx,
                
                
                **{"Name": name, "DocumentVersion": document_version, "InstanceId": instance_id, "Parameters": parameters, "Targets": targets, "ScheduleExpression": schedule_expression, "OutputLocation": output_location, "AssociationName": association_name, "AutomationTargetParameterName": automation_target_parameter_name, "MaxErrors": max_errors, "MaxConcurrency": max_concurrency, "ComplianceSeverity": compliance_severity, "SyncCompliance": sync_compliance, "ApplyOnlyAtCronInterval": apply_only_at_cron_interval, "CalendarNames": calendar_names, "TargetLocations": target_locations}
            )
            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.exec.boto3.client.ssm.describe_association(name)
    result["changes"] = differ.deep_diff(before, after)
    return result

async def absent(hub, ctx, name: Text = None, instance_id: Text = None, association_id: Text = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Disassociates the specified Amazon Web Services Systems Manager document (SSM document) from the specified
    instance. If you created the association by using the Targets parameter, then you must delete the association by
    using the association ID. When you disassociate a document from an instance, it doesn't change the configuration
    of the instance. To change the configuration state of an instance after you disassociate a document, you must
    create a new document with the desired configuration and associate it with the instance.

    Args:
        name(Text, optional): The name of the SSM document. Defaults to None.
        instance_id(Text, optional): The instance ID.   InstanceId has been deprecated. To specify an instance ID for an association,
            use the Targets parameter. Requests that include the parameter InstanceID with Systems Manager
            documents (SSM documents) that use schema version 2.0 or later will fail. In addition, if you
            use the parameter InstanceId, you can't use the parameters AssociationName, DocumentVersion,
            MaxErrors, MaxConcurrency, OutputLocation, or ScheduleExpression. To use these parameters, you
            must use the Targets parameter. Defaults to None.
        association_id(Text, optional): The association ID that you want to delete. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

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

    

    before = await hub.exec.boto3.client.ssm.describe_association(name)

    if not before:
        result["comment"] = f"'{name}' already absent"
    else:
        try:
            ret = await hub.exec.boto3.client.ssm.delete_association(
                ctx,
                
                
                **{"Name": name, "InstanceId": instance_id, "AssociationId": association_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.exec.boto3.client.ssm.describe_association(name)
    result["changes"] = differ.deep_diff(before, after)
    return result

