{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Pinpoint resource stack creation using Amplify CLI",
  "Parameters": {
    "appName": {
      "Type": "String"
    },
    "appId": {
      "Type": "String",
      "Default": "NONE"
    },
    "roleName": {
      "Type": "String"
    },
    "cloudWatchPolicyName": {
      "Type": "String"
    },
    "pinpointPolicyName": {
      "Type": "String"
    },
    "authPolicyName": {
      "Type": "String"
    },
    "unauthPolicyName": {
      "Type": "String"
    },
    "authRoleName": {
      "Type": "String"
    },
    "unauthRoleName": {
      "Type": "String"
    },
    "authRoleArn": {
      "Type": "String"
    },
    "env": {
      "Type": "String"
    }
  },
  "Metadata": {
    "AWS::CloudFormation::Interface": {
      "ParameterGroups": [
        {
          "Label": {
            "default": "Creating pinpoint app"
          },
          "Parameters": ["appName"]
        }
      ]
    }
  },
  "Conditions": {
    "ShouldCreatePinpointApp": {
      "Fn::Equals": [
        {
          "Ref": "appId"
        },
        "NONE"
      ]
    },
    "ShouldNotCreateEnvResources": {
      "Fn::Equals": [
        {
          "Ref": "env"
        },
        "NONE"
      ]
    }
  },
  "Resources": {
    "LambdaExecutionRole": {
      "Condition": "ShouldCreatePinpointApp",
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": {
          "Fn::If": [
            "ShouldNotCreateEnvResources",
            {
              "Ref": "roleName"
            },
            {
              "Fn::Join": [
                "",
                [
                  {
                    "Ref": "roleName"
                  },
                  "-",
                  {
                    "Ref": "env"
                  }
                ]
              ]
            }
          ]
        },
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": ["lambda.amazonaws.com"]
              },
              "Action": ["sts:AssumeRole"]
            }
          ]
        },
        "Policies": [
          {
            "PolicyName": {
              "Ref": "cloudWatchPolicyName"
            },
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                  ],
                  "Resource": "arn:aws:logs:*:*:*"
                }
              ]
            }
          },
          {
            "PolicyName": {
              "Ref": "pinpointPolicyName"
            },
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Action": ["mobileanalytics:*", "mobiletargeting:*"],
                  "Resource": "*"
                }
              ]
            }
          }
        ]
      }
    },
    "PinpointFunction": {
      "Type": "AWS::Lambda::Function",
      "Condition": "ShouldCreatePinpointApp",
      "Properties": {
        "Code": {
          "ZipFile": {
            "Fn::Join": [
              "\n",
              [
                "const response = require('cfn-response');",
                "const aws = require('aws-sdk');",
                "exports.handler = function(event, context) {",
                "    if (event.RequestType == 'Delete') {",
                "        response.send(event, context, response.SUCCESS);",
                "        return;",
                "    }",
                "    if (event.RequestType == 'Update') {",
                "        response.send(event, context, response.SUCCESS);",
                "        return;",
                "    }",
                "    if (event.RequestType == 'Create') {",
                "       const appName = event.ResourceProperties.appName;",
                "       let responseData = {};",
                "       const params = {",
                "           CreateApplicationRequest: {",
                "               Name: appName",
                "           }",
                "       };",
                "       const pinpoint = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.region });",
                "       pinpoint.createApp(params).promise()",
                "           .then((res) => {",
                "               responseData = res.ApplicationResponse;",
                "               response.send(event, context, response.SUCCESS, responseData);",
                "           }).catch((err) => {",
                "               console.log(err.stack);",
                "               responseData = {Error: err};",
                "               response.send(event, context, response.FAILED, responseData);",
                "               throw err;",
                "           });",
                "    }",
                "};"
              ]
            ]
          }
        },
        "Handler": "index.handler",
        "Runtime": "nodejs8.10",
        "Timeout": "300",
        "Role": {
          "Fn::GetAtt": ["LambdaExecutionRole", "Arn"]
        }
      }
    },
    "PinpointFunctionOutputs": {
      "Type": "Custom::LambdaCallout",
      "Condition": "ShouldCreatePinpointApp",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["PinpointFunction", "Arn"]
        },
        "region": {
          "Fn::FindInMap": [
            "RegionMapping",
            {
              "Ref": "AWS::Region"
            },
            "pinpointRegion"
          ]
        },
        "appName": {
          "Fn::If": [
            "ShouldNotCreateEnvResources",
            {
              "Ref": "appName"
            },
            {
              "Fn::Join": [
                "",
                [
                  {
                    "Ref": "appName"
                  },
                  "-",
                  {
                    "Ref": "env"
                  }
                ]
              ]
            }
          ]
        }
      }
    },
    "CognitoUnauthPolicy": {
      "Type": "AWS::IAM::Policy",
      "Condition": "ShouldCreatePinpointApp",
      "Properties": {
        "PolicyName": {
          "Ref": "unauthPolicyName"
        },
        "Roles": [
          {
            "Ref": "unauthRoleName"
          }
        ],
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "mobiletargeting:PutEvents",
                "mobiletargeting:UpdateEndpoint",
                "mobiletargeting:GetUserEndpoints"
              ],
              "Resource": [
                {
                  "Fn::If": [
                    "ShouldCreatePinpointApp",
                    {
                      "Fn::Join": [
                        "",
                        [
                          "arn:aws:mobiletargeting:*:",
                          {
                            "Fn::Select": [
                              "4",
                              {
                                "Fn::Split": [
                                  ":",
                                  {
                                    "Ref": "authRoleArn"
                                  }
                                ]
                              }
                            ]
                          },
                          ":apps/",
                          {
                            "Fn::GetAtt": ["PinpointFunctionOutputs", "Id"]
                          },
                          "*"
                        ]
                      ]
                    },
                    {
                      "Fn::Join": [
                        "",
                        [
                          "arn:aws:mobiletargeting:*:",
                          {
                            "Fn::Select": [
                              "4",
                              {
                                "Fn::Split": [
                                  ":",
                                  {
                                    "Ref": "authRoleArn"
                                  }
                                ]
                              }
                            ]
                          },
                          ":apps/",
                          {
                            "Ref": "appId"
                          },
                          "*"
                        ]
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    },
    "CognitoAuthPolicy": {
      "Type": "AWS::IAM::Policy",
      "Condition": "ShouldCreatePinpointApp",
      "Properties": {
        "PolicyName": {
          "Ref": "authPolicyName"
        },
        "Roles": [
          {
            "Ref": "authRoleName"
          }
        ],
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "mobiletargeting:PutEvents",
                "mobiletargeting:UpdateEndpoint",
                "mobiletargeting:GetUserEndpoints"
              ],
              "Resource": [
                {
                  "Fn::If": [
                    "ShouldCreatePinpointApp",
                    {
                      "Fn::Join": [
                        "",
                        [
                          "arn:aws:mobiletargeting:*:",
                          {
                            "Fn::Select": [
                              "4",
                              {
                                "Fn::Split": [
                                  ":",
                                  {
                                    "Ref": "authRoleArn"
                                  }
                                ]
                              }
                            ]
                          },
                          ":apps/",
                          {
                            "Fn::GetAtt": ["PinpointFunctionOutputs", "Id"]
                          },
                          "*"
                        ]
                      ]
                    },
                    {
                      "Fn::Join": [
                        "",
                        [
                          "arn:aws:mobiletargeting:*:",
                          {
                            "Fn::Select": [
                              "4",
                              {
                                "Fn::Split": [
                                  ":",
                                  {
                                    "Ref": "authRoleArn"
                                  }
                                ]
                              }
                            ]
                          },
                          ":apps/",
                          {
                            "Ref": "appId"
                          },
                          "*"
                        ]
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    }
  },
  "Outputs": {
    "Region": {
      "Value": {
        "Fn::FindInMap": [
          "RegionMapping",
          {
            "Ref": "AWS::Region"
          },
          "pinpointRegion"
        ]
      }
    },
    "Id": {
      "Value": {
        "Fn::If": [
          "ShouldCreatePinpointApp",
          {
            "Fn::GetAtt": ["PinpointFunctionOutputs", "Id"]
          },
          {
            "Ref": "appId"
          }
        ]
      }
    },
    "appName": {
      "Value": {
        "Fn::If": [
          "ShouldCreatePinpointApp",
          {
            "Fn::GetAtt": ["PinpointFunctionOutputs", "Name"]
          },
          {
            "Ref": "appName"
          }
        ]
      }
    }
  },
  "Mappings": {
    "RegionMapping": {
      "us-east-1": {
        "pinpointRegion": "us-east-1"
      },
      "us-east-2": {
        "pinpointRegion": "us-east-1"
      },
      "sa-east-1": {
        "pinpointRegion": "us-east-1"
      },
      "ca-central-1": {
        "pinpointRegion": "us-east-1"
      },
      "us-west-1": {
        "pinpointRegion": "us-west-2"
      },
      "us-west-2": {
        "pinpointRegion": "us-west-2"
      },
      "cn-north-1": {
        "pinpointRegion": "us-west-2"
      },
      "cn-northwest-1": {
        "pinpointRegion": "us-west-2"
      },
      "ap-south-1": {
        "pinpointRegion": "us-west-2"
      },
      "ap-northeast-3": {
        "pinpointRegion": "us-west-2"
      },
      "ap-northeast-2": {
        "pinpointRegion": "us-west-2"
      },
      "ap-southeast-1": {
        "pinpointRegion": "us-west-2"
      },
      "ap-southeast-2": {
        "pinpointRegion": "us-west-2"
      },
      "ap-northeast-1": {
        "pinpointRegion": "us-west-2"
      },
      "eu-central-1": {
        "pinpointRegion": "eu-central-1"
      },
      "eu-west-1": {
        "pinpointRegion": "eu-west-1"
      },
      "eu-west-2": {
        "pinpointRegion": "eu-west-1"
      },
      "eu-west-3": {
        "pinpointRegion": "eu-west-1"
      }
    }
  }
}
