import {
  Stack,
  aws_ec2 as ec2,
  aws_rds as rds,
  StackProps,
  RemovalPolicy,
} from 'aws-cdk-lib';
import { Port } from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
import { BuildConfig } from '../utils/build-config';
import { ClusterInstance } from 'aws-cdk-lib/aws-rds';

export class MccDBInfraStack extends Stack {
  public readonly mccDB: rds.DatabaseCluster;
  public readonly mccDBSecurityGroup: ec2.SecurityGroup;

  credentials = rds.Credentials.fromGeneratedSecret('mccAdmin');

  constructor(scope: Construct, id: string, buildConfig: BuildConfig, props: StackProps) {
    super(scope, id, props);

    const vpc = ec2.Vpc.fromLookup(
      this,
      `${buildConfig.Environment}-${buildConfig.ApplicationShortName}MccVPC`,
      {
        vpcId: buildConfig.Parameters.VPC,
      }
    );

    const dbSecurityGroup = new ec2.SecurityGroup(
      this,
      `${buildConfig.Environment}${buildConfig.ApplicationShortName}MccDBSecurityGroup`,
      {
        vpc: vpc,
        securityGroupName: `${buildConfig.Environment}-${buildConfig.ApplicationShortName}DBSecurityGroup`,
      }
    );

    const mccDB = new rds.DatabaseCluster(this, `${buildConfig.Environment}${buildConfig.ApplicationShortName}MccDB`, {
        engine: rds.DatabaseClusterEngine.auroraPostgres({
            version: rds.AuroraPostgresEngineVersion.VER_17_4,
            }) ,
        vpc,
        writer: ClusterInstance.serverlessV2('writer') ,
        credentials: this.credentials,
        defaultDatabaseName: 'mccdb',
        securityGroups: [dbSecurityGroup],
        serverlessV2MinCapacity: 0,
        serverlessV2MaxCapacity: 64,
        enableDataApi: true,
        clusterIdentifier: `${buildConfig.Environment}-${buildConfig.ApplicationShortName}-mccdb`,
        removalPolicy: RemovalPolicy.RETAIN
    });

    const lambdaSecurityGroup = new ec2.SecurityGroup(
      this,
      `${buildConfig.Environment}${buildConfig.ApplicationShortName}MccDBLambdaSecurityGroup`,
      {
        vpc: vpc,
        securityGroupName: `${buildConfig.Environment}-${buildConfig.ApplicationShortName}DBLambdaSecurityGroup`,
      }
    );

    dbSecurityGroup.addIngressRule(
      lambdaSecurityGroup,
      Port.tcp(mccDB.clusterEndpoint.port),
      'Allow connection from Lambda Function to DB'
    );

    dbSecurityGroup.addIngressRule(
      ec2.Peer.ipv4('10.0.0.0/8'),
      Port.tcp(mccDB.clusterEndpoint.port),
      'Allow connection from internal network'
    );

    this.mccDB = mccDB;
    this.mccDBSecurityGroup = lambdaSecurityGroup;
  }
}