import re

import inflection
import troposphere as tp
from troposphere import apigateway, awslambda

from deploy.utils import camelize


def _generate_attachment_parameters(functions):
    for f in functions:
        # yield tp.Parameter(
        #     f['name']+'Resource',
        #     Description=f['name'] + " Resource",
        #     Type="String"
        # )
        yield tp.Parameter(
            camelize(f['function_name'])+'Resource',
            Description=camelize(f['function_name']) + " Resource Arn",
            Type="String"
        )
        yield tp.Parameter(
            f['name'] + 'Arn',
            Description=f['name'] + " Arn",
            Type="String"
        )
    yield tp.Parameter(
        "RestApiId",
        Description="RestApiId Reference",
        Type="String"
    )


def _generate_attachment_resource(functions):
    for f in functions:
        params = re.findall('{([a-zA-Z0-9_-]+)}', f['path'])
        yield apigateway.Method(
            f['name'] + 'Attachment',
            AuthorizationType="NONE",
            HttpMethod=f['method'].upper(),
            ResourceId=tp.Ref(camelize(f['function_name'])+'Resource'),
            RestApiId=tp.Ref("RestApiId"),
            Integration=apigateway.Integration(
                Type="AWS_PROXY",
                Uri=tp.Sub("arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${"+f['name']+"Arn}/invocations"),
                IntegrationHttpMethod="POST"
            ),
            RequestParameters={"method.request.path."+k: True for k in params},
            MethodResponses=[
                apigateway.MethodResponse(
                    StatusCode="200"
                ),
                apigateway.MethodResponse(
                    StatusCode="400"
                ),
                apigateway.MethodResponse(
                    StatusCode="401"
                ),
                apigateway.MethodResponse(
                    StatusCode="404"
                )
            ]
        )

def _generate_invoke_permissions(functions):
    for f in functions:
        yield awslambda.Permission(
            f['name'] + 'InvokePermission',
            Action="lambda:InvokeFunction",
            Principal="apigateway.amazonaws.com",
            SourceArn=tp.Sub("arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${RestApiId}/*/*/*"),
            FunctionName=tp.Ref(f['name']+"Arn")
        )


def generate_attachments_template(functions, conio_env_param):
    attachment_template = tp.Template()
    attachment_template.add_parameter(conio_env_param)

    for p in _generate_attachment_parameters(functions):
        attachment_template.add_parameter(p)

    for a in _generate_attachment_resource(functions):
        attachment_template.add_resource(a)

    for p in _generate_invoke_permissions(functions):
        attachment_template.add_resource(p)

    return attachment_template.to_yaml()