text: # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  # SPDX-License-Identifier: MIT-0
  
  import aws_cdk.core as cdk
  import aws_cdk.pipelines as pipelines
  import aws_cdk.aws_codepipeline as codepipeline
  import aws_cdk.aws_codepipeline_actions as codepipeline_actions
  import aws_cdk.aws_iam as iam
  
  from .configuration import (
      DEPLOYMENT, GITHUB_REPOSITORY_NAME, GITHUB_REPOSITORY_OWNER_NAME, GITHUB_TOKEN,
      get_logical_id_prefix, get_all_configurations, get_resource_name_prefix,
  )
  from .pipeline_deploy_stage import PipelineDeployStage
  
  
  class PipelineStack(cdk.Stack):
      def __init__(
          self,
          scope: cdk.Construct,
          construct_id: str,
          target_environment: str,
          target_branch: str,
          target_aws_env: dict,
          **kwargs
      ) -> None:
          """
          CloudFormation stack to create CDK Pipeline resources (Code Pipeline, Code Build, and ancillary resources).
  
          @param scope cdk.Construct: Parent of this stack, usually an App or a Stage, but could be any construct.
          @param construct_id str:
              The construct ID of this stack. If stackName is not explicitly defined,
              this id (and any parent IDs) will be used to determine the physical ID of the stack.
          @param target_environment str: The target environment for stacks in the deploy stage
          @param target_branch str: The source branch for polling
          @param target_aws_env dict: The CDK env variable used for stacks in the deploy stage
          """
          super().__init__(scope, construct_id, **kwargs)
  
          self.create_environment_pipeline(
              target_environment,
              target_branch,
              target_aws_env
          )
  
      def create_environment_pipeline(self, target_environment, target_branch, target_aws_env):
          """
          Creates CloudFormation stack to create CDK Pipeline resources such as:
          Code Pipeline, Code Build, and ancillary resources.
  
          @param target_environment str: The target environment for stacks in the deploy stage
          @param target_branch str: The source branch for polling
          @param target_aws_env dict: The CDK env variable used for stacks in the deploy stage
          """
          mappings = get_all_configurations()
          source_artifact = codepipeline.Artifact()
          cloud_assembly_artifact = codepipeline.Artifact()
          logical_id_prefix = get_logical_id_prefix()
          resource_name_prefix = get_resource_name_prefix()
  
          pipeline = pipelines.CdkPipeline(
              self,
              f'{target_environment}{logical_id_prefix}DataLakeEtlPipeline',
              pipeline_name=f'{target_environment.lower()}-{resource_name_prefix}-datalake-etl-pipeline',
              cloud_assembly_artifact=cloud_assembly_artifact,
              source_action=codepipeline_actions.GitHubSourceAction(
                  action_name='GitHub',
                  branch=target_branch,
                  output=source_artifact,
                  oauth_token=cdk.SecretValue.secrets_manager(mappings[DEPLOYMENT][GITHUB_TOKEN]),
                  trigger=codepipeline_actions.GitHubTrigger.POLL,
                  owner=mappings[DEPLOYMENT][GITHUB_REPOSITORY_OWNER_NAME],
                  repo=mappings[DEPLOYMENT][GITHUB_REPOSITORY_NAME],
              ),
              synth_action=pipelines.SimpleSynthAction.standard_npm_synth(
                  source_artifact=source_artifact,
                  cloud_assembly_artifact=cloud_assembly_artifact,
                  install_command='npm install -g aws-cdk && pip3 install -r requirements.txt',
                  # TODO: Automate unit testing
                  # build_command='pytest unit_tests',
                  role_policy_statements=[
                      iam.PolicyStatement(
                          sid='EtlSecretsManagerPolicy',
                          effect=iam.Effect.ALLOW,
                          actions=[
                              'secretsmanager:*',
                          ],
                          resources=[
                              f'arn:aws-us-gov:secretsmanager:{self.region}:{self.account}:secret:/DataLake/*',
                          ],
                      ),
                      iam.PolicyStatement(
                          sid='EtlKmsPolicy',
                          effect=iam.Effect.ALLOW,
                          actions=[
                              'kms:*',
                          ],
                          resources=[
                              '*',
                          ],
                      ),
                      iam.PolicyStatement(
                          sid='EtlVpcPolicy',
                          effect=iam.Effect.ALLOW,
                          actions=[
                              'vpc:*',
                          ],
                          resources=[
                              '*',
                          ],
                      ),
                      iam.PolicyStatement(
                          sid='EtlEc2Policy',
                          effect=iam.Effect.ALLOW,
                          actions=[
                              'ec2:*',
                          ],
                          resources=[
                              '*',
                          ],
                      ),
                  ],
                  synth_command=f'export ENV={target_environment} && cdk synth --verbose',
              ),
              cross_account_keys=True,
          )
  
          deploy_stage = PipelineDeployStage(
              self,
              target_environment,
              target_environment=target_environment,
              env=target_aws_env,
          )
          pipeline.add_application_stage(deploy_stage)
  