import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as elasticache from 'aws-cdk-lib/aws-elasticache';
import { Construct } from 'constructs';
import { config } from '../../config'; // Import the configuration
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3n from 'aws-cdk-lib/aws-s3-notifications';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import { ServiceNamespace } from 'aws-cdk-lib/aws-applicationautoscaling';

export interface BackendDeploymentNotificationStackProps extends cdk.StackProps {
  accountStage: string;
  account: string;
}

export class BackendDeploymentNotificationStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: BackendDeploymentNotificationStackProps) {
    super(scope, id, props);

    if (props.accountStage === 'prod') {
      // Define the Lambda function
      // Create Lambda layer with dependencies
      const dependenciesLayer = new lambda.LayerVersion(this, 'BackendDeploymentNotificationDependences', {
        code: lambda.Code.fromAsset('lambda/prod-deploy-kick-off-notifier/layers', {
          bundling: {
            image: lambda.Runtime.PYTHON_3_11.bundlingImage,
            command: ['bash', '-c', 'pip install -r requirements.txt -t /asset-output/python && ' + 'cp requirements.txt /asset-output/'],
          },
        }),
        compatibleRuntimes: [lambda.Runtime.PYTHON_3_11],
        description: 'Lambda layer with Python dependencies',
      });

      const deploymentKickOffNotifier = new lambda.Function(this, 'DeploymentKickOffNotifier', {
        functionName: 'backend-deployment-kick-off-notifier',
        runtime: lambda.Runtime.PYTHON_3_11,
        handler: 'main.lambda_handler',
        code: lambda.Code.fromAsset('lambda/prod-deploy-kick-off-notifier'),
        layers: [dependenciesLayer],
      });

      deploymentKickOffNotifier.addToRolePolicy(
        new iam.PolicyStatement({
          actions: [
            'sts:GetCallerIdentity',
            'ecs:ListTaskDefinitions',
            'ecs:describeTaskDefinition',
            'ecs:registerTaskDefinition',
            'ecs:UpdateService',
            'ecs:RunTask',
            'ecs:UpdateService',
            'ecs:RunTask',
            'ecs:DescribeTasks',
            'ecs:DescribeServices',
            'ecs:DescribeClusters',
            'ecs:DescribeTasks',
            'ecs:DescribeTaskDefinition',
            'ecs:DescribeTaskSets',
            'ecs:DescribeTaskSet',
            'ecs:DescribeTasks',
            'ecs:DescribeClusters',
            'ecs:DescribeTasks',
            'ecr:DescribeImages',
            'iam:PassRole',
            'ssm:PutParameter',
            'codedeploy:CreateDeployment',
            'codedeploy:GetDeployment',
            'codedeploy:GetDeploymentConfig',
            'codedeploy:GetApplication',
            'codedeploy:GetApplicationRevision',
            'codedeploy:RegisterApplicationRevision',
            'codedeploy:GetDeploymentConfig',
            'codedeploy:GetDeploymentGroup',
            'codedeploy:GetDeploymentTarget',
            'codedeploy:ListApplications',
            'codedeploy:ListDeployments',
            'codedeploy:ListDeploymentConfigs',
            'codedeploy:ListDeploymentGroups',
            'codedeploy:ListDeploymentTargets',
            'codedeploy:StopDeployment',
            'sqs:SendMessage',
            'sqs:GetQueueUrl',
            'sqs:GetQueueAttributes',
            'sqs:ReceiveMessage',
            'sqs:DeleteMessage',
          ],
          resources: ['*'],
        })
      );

      // Create an EventBridge rule to capture deployment kickoff events
      const deployKickoffRule = new events.Rule(this, 'DeployKickoffRule', {
        ruleName: 'backend-deployment-kick-off-rule',
        eventPattern: {
          source: ['aws.codedeploy'],
          detailType: ['AWS API Call via CloudTrail'],
          detail: {
            eventSource: ['codedeploy.amazonaws.com'],
            eventName: ['CreateDeployment'],
          },
        },
      });

      // Add the Lambda function as a target for the EventBridge rule
      deployKickoffRule.addTarget(new targets.LambdaFunction(deploymentKickOffNotifier));

      // Grant necessary permissions to the Lambda function
      deploymentKickOffNotifier.addToRolePolicy(
        new iam.PolicyStatement({
          actions: ['events:PutEvents'],
          resources: ['*'],
        })
      );
    }
  }
}
