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

hub.exec.boto3.client.cloudformation.create_stack_instances
hub.exec.boto3.client.cloudformation.delete_stack_instances
hub.exec.boto3.client.cloudformation.describe_stack_instance
hub.exec.boto3.client.cloudformation.list_stack_instances
hub.exec.boto3.client.cloudformation.update_stack_instances
"""



from typing import *
import dict_tools.differ as differ
async def present(hub, ctx, name: Text, stack_set_name: Text, regions: List, accounts: List = None, deployment_targets: Dict = None, parameter_overrides: List = None, operation_preferences: Dict = None, operation_id: Text = None, call_as: Text = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Creates stack instances for the specified accounts, within the specified Regions. A stack instance refers to a
    stack in a specific account and Region. You must specify at least one value for either Accounts or
    DeploymentTargets, and you must specify at least one value for Regions.

    Args:
        name(Text): A name, ID, or JMES search path to identify the resource.
        stack_set_name(Text): The name or unique ID of the stack set that you want to create stack instances from.
        accounts(List, optional): [Self-managed permissions] The names of one or more accounts that you want to create stack
            instances in the specified Region(s) for. You can specify Accounts or DeploymentTargets, but not
            both. Defaults to None.
        deployment_targets(Dict, optional): [Service-managed permissions] The Organizations accounts for which to create stack instances in
            the specified Regions. You can specify Accounts or DeploymentTargets, but not both. Defaults to None.
        regions(List): The names of one or more Regions where you want to create stack instances using the specified
            accounts.
        parameter_overrides(List, optional): A list of stack set parameters whose values you want to override in the selected stack
            instances. Any overridden parameter values will be applied to all stack instances in the
            specified accounts and Regions. When specifying parameters and their values, be aware of how
            CloudFormation sets parameter values during stack instance operations:   To override the current
            value for a parameter, include the parameter and specify its value.   To leave an overridden
            parameter set to its present value, include the parameter and specify UsePreviousValue as true.
            (You cannot specify both a value and set UsePreviousValue to true.)   To set an overridden
            parameter back to the value specified in the stack set, specify a parameter list but do not
            include the parameter in the list.   To leave all parameters set to their present values, do not
            specify this property at all.   During stack set updates, any parameter values overridden for a
            stack instance are not updated, but retain their overridden value. You can only override the
            parameter values that are specified in the stack set; to add or delete a parameter itself, use
            UpdateStackSet to update the stack set template. Defaults to None.
        operation_preferences(Dict, optional): Preferences for how CloudFormation performs this stack set operation. Defaults to None.
        operation_id(Text, optional): The unique identifier for this stack set operation.  The operation ID also functions as an
            idempotency token, to ensure that CloudFormation performs the stack set operation only once,
            even if you retry the request multiple times. You might retry stack set operation requests to
            ensure that CloudFormation successfully received them. If you don't specify an operation ID, the
            SDK generates one automatically.  Repeating this stack set operation with a new operation ID
            retries all stack instances whose status is OUTDATED. Defaults to None.
        call_as(Text, optional): [Service-managed permissions] Specifies whether you are acting as an account administrator in
            the organization's management account or as a delegated administrator in a member account. By
            default, SELF is specified. Use SELF for stack sets with self-managed permissions.   If you are
            signed in to the management account, specify SELF.   If you are signed in to a delegated
            administrator account, specify DELEGATED_ADMIN. Your account must be registered as a delegated
            administrator in the management account. For more information, see Register a delegated
            administrator in the CloudFormation User Guide. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_present:
              aws_auto.cloudformation.stack_instance.present:
                - name: value
                - stack_set_name: value
                - regions: value
    '''
    
    result = dict(comment="", changes= None, name=name, result=True)
    ret = await hub.exec.boto3.client.cloudformation.stack_instance.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.cloudformation.describe_stack_instance(name)

    if before:
        result["comment"] = f"'{name}' already exists"
    else:
        try:
            ret = await hub.exec.boto3.client.cloudformation.create_stack_instances(
                ctx,
                
                
                **{"StackSetName": stack_set_name, "Accounts": accounts, "DeploymentTargets": deployment_targets, "Regions": regions, "ParameterOverrides": parameter_overrides, "OperationPreferences": operation_preferences, "OperationId": operation_id, "CallAs": call_as}
            )
            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.cloudformation.describe_stack_instance(name)
    result["changes"] = differ.deep_diff(before, after)
    return result

async def absent(hub, ctx, name: Text, stack_set_name: Text, regions: List, retain_stacks: bool, accounts: List = None, deployment_targets: Dict = None, operation_preferences: Dict = None, operation_id: Text = None, call_as: Text = None)  -> Dict[str, Any]:
    r'''
    **Autogenerated function**
    
    Deletes stack instances for the specified accounts, in the specified Regions.

    Args:
        name(Text): A name, ID, or JMES search path to identify the resource.
        stack_set_name(Text): The name or unique ID of the stack set that you want to delete stack instances for.
        accounts(List, optional): [Self-managed permissions] The names of the accounts that you want to delete stack instances
            for. You can specify Accounts or DeploymentTargets, but not both. Defaults to None.
        deployment_targets(Dict, optional): [Service-managed permissions] The Organizations accounts from which to delete stack instances.
            You can specify Accounts or DeploymentTargets, but not both. Defaults to None.
        regions(List): The Regions where you want to delete stack set instances.
        operation_preferences(Dict, optional): Preferences for how CloudFormation performs this stack set operation. Defaults to None.
        retain_stacks(bool): Removes the stack instances from the specified stack set, but doesn't delete the stacks. You
            can't reassociate a retained stack or add an existing, saved stack to a new stack set. For more
            information, see Stack set operation options.
        operation_id(Text, optional): The unique identifier for this stack set operation.  If you don't specify an operation ID, the
            SDK generates one automatically.  The operation ID also functions as an idempotency token, to
            ensure that CloudFormation performs the stack set operation only once, even if you retry the
            request multiple times. You can retry stack set operation requests to ensure that CloudFormation
            successfully received them. Repeating this stack set operation with a new operation ID retries
            all stack instances whose status is OUTDATED. Defaults to None.
        call_as(Text, optional): [Service-managed permissions] Specifies whether you are acting as an account administrator in
            the organization's management account or as a delegated administrator in a member account. By
            default, SELF is specified. Use SELF for stack sets with self-managed permissions.   If you are
            signed in to the management account, specify SELF.   If you are signed in to a delegated
            administrator account, specify DELEGATED_ADMIN. Your account must be registered as a delegated
            administrator in the management account. For more information, see Register a delegated
            administrator in the CloudFormation User Guide. Defaults to None.

    Returns:
        Dict[str, Any]

    Examples:

        .. code-block:: sls

            resource_is_absent:
              aws_auto.cloudformation.stack_instance.absent:
                - name: value
                - stack_set_name: value
                - regions: value
                - retain_stacks: value
    '''
    
    result = dict(comment="", changes= None, name=name, result=True)
    ret = await hub.exec.boto3.client.cloudformation.stack_instance.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.cloudformation.describe_stack_instance(name)

    if not before:
        result["comment"] = f"'{name}' already absent"
    else:
        try:
            ret = await hub.exec.boto3.client.cloudformation.delete_stack_instances(
                ctx,
                
                
                **{"StackSetName": stack_set_name, "Accounts": accounts, "DeploymentTargets": deployment_targets, "Regions": regions, "OperationPreferences": operation_preferences, "RetainStacks": retain_stacks, "OperationId": operation_id, "CallAs": call_as}
            )
            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.cloudformation.describe_stack_instance(name)
    result["changes"] = differ.deep_diff(before, after)
    return result

