import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep, CodeBuildStep } from 'aws-cdk-lib/pipelines';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
import { AppDeploymentStage } from './app-deployment-stage';

export class CdkPipelineStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // S3 bucket names must be globally unique.
    const bucketName = 'suno-cdk-pipeline-source-bucket';

    const sourceBucket = new s3.Bucket(this, 'CdkSourceBucket', {
      bucketName: bucketName,
      versioned: true,
      // Consider your data retention policy. DESTROY is for dev/testing.
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    });

    const pipeline = new CodePipeline(this, 'CdkPipeline', {
      pipelineName: 'suno-cdk-pipeline',
      crossAccountKeys: true, 
      synth: new ShellStep('Synth', {
        input: CodePipelineSource.s3(sourceBucket, 'source.zip'),
        // These commands assume the source.zip contains the content of the 'suno-cdk' directory
        commands: ['npm ci', 'npm run build', 'npx cdk synth'],
        primaryOutputDirectory: 'cdk.out',
      }),
    });

    const devDeploy = new AppDeploymentStage(this, 'Dev', {
      accountStage: 'dev',
      env: props?.env,
    });

    pipeline.addStage(devDeploy);

    // Add staging stage
    const stagingDeploy = new AppDeploymentStage(this, 'Staging', {
      accountStage: 'staging',
      env: {
        account: '590183763515', // staging account ID
        region: 'us-east-2',
      },
    });

    pipeline.addStage(stagingDeploy);

    // Add production stage for us-east-1 (ProdS3Stack only)
    const prodUSEast1Deploy = new AppDeploymentStage(this, 'Prod-us-east-1', {
      accountStage: 'prod-us-east-1',
      env: {
        account: '734185074900', // production account ID
        region: 'us-east-1',
      },
    });

    pipeline.addStage(prodUSEast1Deploy);

    // Add production stage for us-east-2 (all other stacks)
    const prodUSEast2Deploy = new AppDeploymentStage(this, 'Prod', {
      accountStage: 'prod',
      env: {
        account: '734185074900', // production account ID
        region: 'us-east-2',
      },
    });

    pipeline.addStage(prodUSEast2Deploy);

    // Add production stage for eu-central-1 (EventStreamStack only)
    const prodEUCentral1Deploy = new AppDeploymentStage(this, 'Prod-eu-central-1', {
      accountStage: 'prod-eu-central-1',
      env: {
        account: '734185074900', // production account ID
        region: 'eu-central-1',
      },
    });

    pipeline.addStage(prodEUCentral1Deploy);

    // Add production stage for ap-southeast-1 (EventStreamStack only)
    const prodAPSoutheast1Deploy = new AppDeploymentStage(this, 'Prod-ap-southeast-1', {
      accountStage: 'prod-ap-southeast-1',
      env: {
        account: '734185074900', // production account ID
        region: 'ap-southeast-1',
      },
    });

    pipeline.addStage(prodAPSoutheast1Deploy);

    new cdk.CfnOutput(this, 'SourceBucketName', {
      value: sourceBucket.bucketName,
      description: "Upload the zipped contents of 'suno-cdk' as 'source.zip' to this S3 bucket to trigger the pipeline.",
    });
  }
} 