import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import { Construct } from 'constructs';
import { studioSecrets } from '../secrets/studio-secrets';
import { datadogSecrets } from '../secrets/dd-secret';
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
import { DatadogAgentServiceProps } from './datadog-agent-utils';

export class DatadogPostgresService extends Construct {
  public service: ecs.FargateService;

  constructor(scope: Construct, id: string, props: DatadogAgentServiceProps) {
    super(scope, id); // registers child construct within BackendInfraStack CDK construct

    const datadogTaskDefinition = new ecs.FargateTaskDefinition(this, 'DatadogTaskDef', {
      memoryLimitMiB: 32768,
      cpu: 8192,
      ephemeralStorageGiB: 200,
      family: `datadog-postgres-${props.accountStage}`,
    });
    const secrets = studioSecrets(this, props.accountStage, true);
    const datadogPostgresSecret = datadogSecrets(this, props.accountStage);

    // if staging
    let dbclusteridentifier = 'suno-main-pgdb-staging-clone';
    let hostnames = [
      'suno-main-pgdb-staging-clone.cnquy64ua61a.us-east-2.rds.amazonaws.com',
      'suno-main-pgdb-staging-clone-instance-2.cnquy64ua61a.us-east-2.rds.amazonaws.com',
    ];

    // if prod
    if (props.accountStage === 'prod') {
      dbclusteridentifier = 'suno-main-postgres-prod-cluster';
      hostnames = [
        'suno-main-postgres-prod-analytics.cnfvffydbwvc.us-east-2.rds.amazonaws.com',
        'suno-main-postgres-prod-instance-2.cnfvffydbwvc.us-east-2.rds.amazonaws.com',
      ];
    }

    const image = ecs.ContainerImage.fromAsset('./lib/backend-infra-stack/ecs/datadog-agent-container', {
      platform: Platform.LINUX_AMD64,
    });

    // Add the Datadog container to the task definition
    const datadogContainer = datadogTaskDefinition.addContainer('DatadogContainer', {
      image,
      logging: new ecs.AwsLogDriver({
        streamPrefix: 'datadog-postgres',
      }),
      environment: {
        DD_SITE: 'datadoghq.com',
        ECS_FARGATE: 'true',
        DD_ENV: props.accountStage,
        DD_INTEGRATIONS_ENABLED: 'true',
        DD_DATABASEMONITORING_ENABLED: 'true',
        DD_DBM_ENABLED: 'true',
        AWS_REGION: 'us-east-2',
      },
      secrets: {
        DD_API_KEY: secrets['DD_API_KEY'],
      },
      cpu: 8192,
      memoryLimitMiB: 32768,
      essential: true,
      healthCheck: {
        command: ['CMD-SHELL', 'agent health'],
        interval: cdk.Duration.seconds(30),
        timeout: cdk.Duration.seconds(5),
        retries: 3,
        startPeriod: cdk.Duration.seconds(15),
      },
      dockerLabels: {
        'com.datadoghq.ad.checks': `{
          "postgres": {
            "init_config": {},
            "instances": [${hostnames
              .map(
                (host) =>
                  `{"dbm": true,"host": "${host}", "port": 5432, "username": "datadog", "password": "${datadogPostgresSecret}", "tags": ["dbclusteridentifier:${dbclusteridentifier}", "dbinstanceidentifier:${
                    host.split('.')[0]
                  }", "env:${props.accountStage}"]}`
              )
              .join(',\n')}]
          }
        }`,
      },
    });

    // Create a security group for the Fargate service
    const datadogSecurityGroup = new ec2.SecurityGroup(this, 'DatadogSecurityGroup', {
      vpc: props.vpc,
      allowAllOutbound: true,
      securityGroupName: `datadog-postgres-sg-${props.accountStage}`,
      description: "Security group for datadog postgres integration service",
    });

    // Define the Fargate service first
    this.service = new ecs.FargateService(this, 'DatadogFargateService', {
      cluster: props.cluster,
      taskDefinition: datadogTaskDefinition,
      serviceName: `datadog-postgres-service-${props.accountStage}`,
      deploymentController: {
        type: ecs.DeploymentControllerType.ECS,
      },
      securityGroups: [datadogSecurityGroup],
      vpcSubnets: {
        subnets: props.subnets,
      },
      enableExecuteCommand: true,
      desiredCount: 1,
    });

  }
}
