import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as eks from 'aws-cdk-lib/aws-eks';
import * as s3 from 'aws-cdk-lib/aws-s3';
import {KubernetesManifest} from "aws-cdk-lib/aws-eks/lib/k8s-manifest";
import {HelmChart} from "aws-cdk-lib/aws-eks";

interface IdeServicesChartProps extends cdk.NestedStackProps {
  cluster: eks.Cluster;
  externalSecret: KubernetesManifest;
  mellumExternalSecret?: KubernetesManifest;
  dataBucket: s3.Bucket;
  serviceAccount: eks.ServiceAccount;
}

export class IdeServicesApp extends cdk.NestedStack {
  ideServicesChart: HelmChart;

  constructor(scope: Construct, id: string, props: IdeServicesChartProps) {
    super(scope, id, props);

    const {cluster, externalSecret, mellumExternalSecret, dataBucket, serviceAccount} = props

    // Deploy application using Helm
    let ideServicesVersion = this.node.tryGetContext('ideServicesChartVersion');
    const useMellum = this.node.tryGetContext('useMellum') || false;
    const mellumPodsCount = this.node.tryGetContext('gpuNodeGroupMinSize') || 1;
    
    this.ideServicesChart = cluster.addHelmChart('IdeServicesChart', {
      chart: 'ide-services-helm',
      repository: 'https://download.jetbrains.com/ide-services/charts/stable',
      namespace: serviceAccount.serviceAccountNamespace,
      release: 'jb-ide-services',
      version: ideServicesVersion,
      values: {
        serviceAccountName: serviceAccount.serviceAccountName,
        ides: {
          config: {
            deploymentUrl: 'http://localhost',
            db: {
              secretName: 'ide-services-rds-credentials'
            },
            storage: {
              type: 's3',
              s3: {
                autoConfiguration: true,
                bucket: dataBucket.bucketName,
              }
            },
            ...(useMellum ? {
              mellum: {
                jwtPrivateKeySecretName: 'ide-services-mellum-credentials',
              }
            } : {})
          },
          resources: {
            requests: {
              cpu: '400m',
              memory: '600Mi',
            },
            limits: {
              cpu: 2,
              memory: '2000Mi',
            },
          },
          metrics: {
            enabled: true,
            serviceMonitor: {
              enabled: true
            }
          },
          logging: {
            enabled: true, // Enable logging
            fluentBit: {   // Fluent Bit configuration for CloudWatch
              cloudWatch: {
                enabled: true,
                region: cdk.Stack.of(this).region, // AWS region
                logGroupName: '/eks/ide-services', // CloudWatch Log Group
                autoCreateLogGroup: true,
                logStreamPrefix: 'ide-services-', // Prefix for log streams
              },
            },
          },
          ingress: {
            enabled: true,
            ingressClassName: "alb",
            annotations: {
              'kubernetes.io/ingress.class': 'alb',
              'alb.ingress.kubernetes.io/scheme': 'internal',
              'alb.ingress.kubernetes.io/target-type': 'ip',
              'alb.ingress.kubernetes.io/listen-ports': '[{"HTTP": 80}]',
              'alb.ingress.kubernetes.io/healthcheck-path': '/actuator/health',
              'alb.ingress.kubernetes.io/success-codes': '200-399',
              'alb.ingress.kubernetes.io/group.name': 'ide-services-group',
              'alb.ingress.kubernetes.io/target-group-name': 'ide-services-target-group',
              'alb.ingress.kubernetes.io/security-groups': cluster.clusterSecurityGroupId
            },
            pathType: 'Prefix'
          },
        },
        ...(useMellum ? {
          aie: {
            mellum: {
              enabled: true,
              config: {
                jwtPublicKeySecretName: 'ide-services-mellum-credentials',
              },
              providerDefaults: {
                resources: {
                  requests: {
                    memory: '12Gi',
                  }
                },
                podNodeSelector: {
                  'node-type': 'gpu',
                  'accelerator': 'gpu'
                },
                replicaCount: mellumPodsCount
              },
              providers: {
                'mellum-all': {
                  model: 'jet-all-medium',
                  image: {
                    registry: "docker.io",
                    repository: "jetbrains/mellum-all-enterprise",
                    tag: '2025.2.9',
                    pullSecrets: ['ide-services-medium-registry-credentials']
                  }
                }
              }
            }
          }
        } : {}),
      },
    });

    // Ensure the external secret is created before the app chart
    this.ideServicesChart.node.addDependency(externalSecret);

    // Ensure the mellum external secret is created before the app chart if mellum is enabled
    if (useMellum && mellumExternalSecret) {
      this.ideServicesChart.node.addDependency(mellumExternalSecret);
    }

    // Ensure the service account is created before the app chart
    this.ideServicesChart.node.addDependency(serviceAccount);
  }
}
