"""Load dependencies."""
import awacs.awslambda
import awacs.dynamodb
import awacs.logs
import awacs.sts
from awacs.aws import Allow, Policy, Principal, Statement
from troposphere import (AccountId, Export, GetAtt, Join, Output, Partition,
                         Ref, Region, Sub, awslambda, iam)

from runway.cfngin.blueprints.base import Blueprint
from runway.cfngin.blueprints.variables.types import CFNString


class BlueprintClass(Blueprint):
    """Blueprint for creating lambda function."""

    VARIABLES = {
        "Code": {
            "type": awslambda.Code,
            "description": "The troposphere.awslambda.Code object "
                           "returned by the aws lambda hook.",
        },
        "AppName": {
            "type": CFNString,
            "description": "Name of app"
        },
        "Entrypoint": {
            "type": CFNString,
            "description": "Lambda function entrypoint.",
            "default": "index.handler"
        }
    }

    def create_resources(self):
        """Create the resources."""
        template = self.template
        variables = self.get_variables()
        app_name = variables['AppName'].ref

        lambda_iam_role = template.add_resource(
            iam.Role(
                'LambdaRole',
                RoleName=Join('-',
                              [app_name,
                               'lambda-role']),
                AssumeRolePolicyDocument=Policy(
                    Version='2012-10-17',
                    Statement=[
                        Statement(
                            Effect=Allow,
                            Action=[awacs.sts.AssumeRole],
                            Principal=Principal('Service',
                                                ['lambda.amazonaws.com'])
                        )
                    ]
                ),
                Path='/service-role/',
                Policies=[
                    iam.Policy(
                        PolicyName=Join('-',
                                        [app_name,
                                         'lambda-policy']),
                        PolicyDocument=Policy(
                            Version='2012-10-17',
                            Statement=[
                                Statement(
                                    Action=[
                                        awacs.logs.CreateLogGroup,
                                        awacs.logs.CreateLogStream,
                                        awacs.logs.PutLogEvents
                                    ],
                                    Effect=Allow,
                                    Resource=[
                                        Join('', [
                                            'arn:',
                                            Partition,
                                            ':logs:',
                                            Region,
                                            ':',
                                            AccountId,
                                            ':log-group:/aws/lambda/',
                                            app_name,
                                            '-*'])
                                    ],
                                    Sid='WriteLogs'
                                )
                            ]
                        )
                    )
                ]
            )
        )

        lambda_function = template.add_resource(
            awslambda.Function(
                'LambdaFunction',
                Code=variables['Code'],
                Handler=variables['Entrypoint'].ref,
                Role=GetAtt(lambda_iam_role, 'Arn'),
                Runtime='python3.6',
                Timeout=30,
                MemorySize=128,
                FunctionName=Join('-', [app_name,
                                        'integrationtest'])
            )
        )

        template.add_output(
            Output(
                lambda_iam_role.title,
                Description='Lambda Role',
                Export=Export(Sub(
                    '${AWS::StackName}-%s' % lambda_iam_role.title
                )),
                Value=Ref(lambda_iam_role)
            )
        )
        template.add_output(
            Output(
                lambda_function.title,
                Description='Lambda Function',
                Export=Export(Sub(
                    '${AWS::StackName}-%s' % lambda_function.title
                )),
                Value=GetAtt(lambda_function, 'Arn')
            )
        )
        template.add_output(
            Output(
                lambda_function.title + 'Name',
                Description='Lambda Function Name',
                Export=Export(Sub(
                    '${AWS::StackName}-%sName' % lambda_function.title
                )),
                Value=Ref(lambda_function)
            )
        )

    def create_template(self):
        self.template.add_version('2010-09-09')
        self.template.add_description('Test Lambda'
                                      ' - {0}'.format('1.0.0'))
        self.create_resources()
