from . import cfg
from .shared import stack_add_res
from . import (mappings, lambdas, securitygroup, loadbalancing,
               autoscaling, iam, codedeploy, route53, events, cloudfront,
               sqs, sns, ecs, ecr, s3, waf, vpc, dynamodb, kms, rds, efs,
               elasticache, cloudformation, logs, apigateway,
               joker, __version__)


def execute_method(RP_cmm):
    for k, v in cfg.CFG_TO_FUNC.items():
        func_name = v['func']
        module_name = v['module']
        module = globals()[module_name]

        if k in list(RP_cmm.keys()):
            RP_value = RP_cmm[k]
            if isinstance(RP_value, str) and RP_value == 'IBOX_SKIP_FUNC':
                continue
            if isinstance(func_name, list):
                for n in func_name:
                    getattr(module, n)(key=k)
                continue
            stacktype_func = f'{func_name}{cfg.stacktype.upper()}'
            if stacktype_func in dir(module):
                getattr(module, stacktype_func)(key=k)
            elif func_name in dir(module):
                getattr(module, func_name)(key=k)
            elif module_name == 'joker':
                # for resources that can be built using only auto_get_props
                joker.Joker(key=k, module=func_name[0], cls=func_name[1])

    stack_add_res()


def generate():
    cfg.func_envrole = cfg.envrole.replace('-', '_')

    try:
        execute_method(cfg.RP_cmm)
    except Exception:
        # in case of error call stack_add_res to empty the cfg Parameters
        # Conditions Mappings Resources Outputs  dicts. This is needed cause
        # get_template "restore base cfg" section do not recursive remove
        # "sub-objetcs" or to say it in a better way:
        # dict clear methods reset the contents,
        # but all references to the same instance will still be present.
        stack_add_res()
        raise

    version_text = f'(Generated by awsibox {__version__})'
    cfg.template.set_description(
        f'{cfg.envrole} {version_text} [{cfg.stacktype}]')
    cfg.template.set_version('2010-09-09')

    return cfg.template
