# Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS AppConfig Feature Flags example

###################################################################################################
##  Template Parameters                                                                         ##
###################################################################################################
Parameters:
  AppName:
    Type: String
    Description: Name of application (no spaces). Value must be globally unique
    Default: appconfig-feature-flags
  AppConfigApplication:
    Type: String
    Description: Id of AppConfig Application
  AppConfigEnvironment:
    Type: String
    Description: Id of AppConfig Environment
  AppConfigConfigurationProfile:
    Type: String
    Description: Id of AppConfig Configuration Profile
  ClientDomains:
    Type: CommaDelimitedList
    Description: Array of domains allowed to use the API
    Default: '*'

###################################################################################################
##  Template Resources                                                                          ##
###################################################################################################
Resources:
  ##  Feature Flags Function
  getFeatureFlags:
    Type: AWS::Serverless::Function
    Properties:
      Handler: getFeatureFlags.handler
      CodeUri: src/getFeatureFlags/
      Runtime: nodejs14.x
      MemorySize: 128
      Timeout: 100
      Layers:
          - !FindInMap [AppConfigLayer, !Ref "AWS::Region", ARN]
          - !Ref FeatureFlagLayer
      Policies:
        - Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - appconfig:GetLatestConfiguration
                - appconfig:StartConfigurationSession
              Resource:
                - !Sub 'arn:aws:appconfig:*:*:application/${AppConfigApplication}/environment/${AppConfigEnvironment}/configuration/${AppConfigConfigurationProfile}'
      Environment:
        Variables:
          APPCONFIG_APPLICATION: !Ref AppConfigApplication
          APPCONFIG_ENVIRONMENT: !Ref AppConfigEnvironment
          APPCONFIG_CONFIGURATION: !Ref AppConfigConfigurationProfile
          # AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS: 45
          # AWS_APPCONFIG_EXTENSION_POLL_TIMEOUT_MILLIS: 3000
          # AWS_APPCONFIG_EXTENSION_HTTP_PORT: 2772
      Events:
        Api:
          Type: HttpApi
          Properties:
            Path: /flags
            Method: GET
            ApiId: !Ref HttpApi

  ##  Products Function
  getAllProducts:
    Type: AWS::Serverless::Function
    Properties:
      Handler: getAllProducts.handler
      CodeUri: src/getAllProducts/
      Runtime: nodejs14.x
      MemorySize: 128
      Timeout: 100
      Layers:
          - !FindInMap [AppConfigLayer, !Ref "AWS::Region", ARN]
          - !Ref FeatureFlagLayer
      Policies:
        - DynamoDBReadPolicy:
            TableName: !Ref DynamoDBTable
        - Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - appconfig:GetLatestConfiguration
                - appconfig:StartConfigurationSession
              Resource:
                - !Sub 'arn:aws:appconfig:*:*:application/${AppConfigApplication}/environment/${AppConfigEnvironment}/configuration/${AppConfigConfigurationProfile}'
      Environment:
        Variables:
          PRODUCT_TABLE: !Ref DynamoDBTable
          APPCONFIG_APPLICATION: !Ref AppConfigApplication
          APPCONFIG_ENVIRONMENT: !Ref AppConfigEnvironment
          APPCONFIG_CONFIGURATION: !Ref AppConfigConfigurationProfile
          AWS_APPCONFIG_EXTENSION_POLL_INTERVAL_SECONDS: 15
          # AWS_APPCONFIG_EXTENSION_POLL_TIMEOUT_MILLIS: 3000
          # AWS_APPCONFIG_EXTENSION_HTTP_PORT: 2772
      Events:
        Api:
          Type: HttpApi
          Properties:
            Path: /products
            Method: GET
            ApiId: !Ref HttpApi
  
  ##  Shared libraries layer
  FeatureFlagLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: src/FeatureFlagLayer/.
      CompatibleRuntimes:
          - nodejs14.x
      RetentionPolicy: Delete
    Metadata:
      BuildMethod: nodejs14.x

  ##  API Gateway
  HttpApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      CorsConfiguration:
        AllowMethods:
          - GET
        AllowHeaders: 
          - '*'
        AllowOrigins: !Ref ClientDomains
  
  ##  Products Table
  DynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    DeletionPolicy: Delete
    Properties:
      AttributeDefinitions:
        -
          AttributeName: id
          AttributeType: N
      KeySchema:
        -
          AttributeName: id
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST

###################################################################################################
##  Mappings                                                                                     ##
###################################################################################################

Mappings:
  ## See layer ARNs https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions.html
  AppConfigLayer: 
    ap-east-1:
      ARN: arn:aws:lambda:ap-east-1:630222743974:layer:AWS-AppConfig-Extension:44
    ap-northeast-3:
      ARN: arn:aws:lambda:ap-northeast-3:706869817123:layer:AWS-AppConfig-Extension:42
    us-east-1:
      ARN: arn:aws:lambda:us-east-1:027255383542:layer:AWS-AppConfig-Extension:61
    us-east-2:
      ARN: arn:aws:lambda:us-east-2:728743619870:layer:AWS-AppConfig-Extension:47
    eu-north-1:
      ARN: arn:aws:lambda:eu-north-1:646970417810:layer:AWS-AppConfig-Extension:86
    ap-northeast-2:
      ARN: arn:aws:lambda:ap-northeast-2:826293736237:layer:AWS-AppConfig-Extension:54
    us-west-2:
      ARN: arn:aws:lambda:us-west-2:359756378197:layer:AWS-AppConfig-Extension:89
    us-west-1:
      ARN: arn:aws:lambda:us-west-1:958113053741:layer:AWS-AppConfig-Extension:61
    ap-northeast-1:
      ARN: arn:aws:lambda:ap-northeast-1:980059726660:layer:AWS-AppConfig-Extension:45
    us-gov-east-1:
      ARN: arn:aws-us-gov:lambda:us-gov-east-1:946561847325:layer:AWS-AppConfig-Extension:20
    af-south-1:
      ARN: arn:aws:lambda:af-south-1:574348263942:layer:AWS-AppConfig-Extension:44
    us-gov-west-1:
      ARN: arn:aws-us-gov:lambda:us-gov-west-1:946746059096:layer:AWS-AppConfig-Extension:20
    ap-southeast-1:
      ARN: arn:aws:lambda:ap-southeast-1:421114256042:layer:AWS-AppConfig-Extension:45
    ap-southeast-2:
      ARN: arn:aws:lambda:ap-southeast-2:080788657173:layer:AWS-AppConfig-Extension:54
    ap-south-1:
      ARN: arn:aws:lambda:ap-south-1:554480029851:layer:AWS-AppConfig-Extension:55
    eu-west-1:
      ARN: arn:aws:lambda:eu-west-1:434848589818:layer:AWS-AppConfig-Extension:59
    eu-west-2:
      ARN: arn:aws:lambda:eu-west-2:282860088358:layer:AWS-AppConfig-Extension:47
    eu-west-3:
      ARN: arn:aws:lambda:eu-west-3:493207061005:layer:AWS-AppConfig-Extension:48"
    eu-south-1:
      ARN: arn:aws:lambda:eu-south-1:203683718741:layer:AWS-AppConfig-Extension:44
    eu-central-1:
      ARN: arn:aws:lambda:eu-central-1:066940009817:layer:AWS-AppConfig-Extension:54
    cn-northwest-1:
      ARN: arn:aws-cn:lambda:cn-northwest-1:615084187847:layer:AWS-AppConfig-Extension:43
    ca-central-1:
      ARN: arn:aws:lambda:ca-central-1:039592058896:layer:AWS-AppConfig-Extension:47
    me-south-1:
      ARN: arn:aws:lambda:me-south-1:559955524753:layer:AWS-AppConfig-Extension:44
    cn-north-1:
      ARN: arn:aws-cn:lambda:cn-north-1:615057806174:layer:AWS-AppConfig-Extension:43
    sa-east-1:
      ARN: arn:aws:lambda:sa-east-1:000010852771:layer:AWS-AppConfig-Extension:61

###################################################################################################
##  Template outputs                                                                             ##
###################################################################################################

Outputs:
  HttpApiUrl:
    Description: URL of your API endpoint
    Value:
      Fn::Sub: 'https://${HttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}'
  DynamoDBTableName:
    Description: The name of your DynamoDB table
    Value: !Ref DynamoDBTable