/*
locals {
  dna_api_secrets_list = [
    "ATLAS_CLIENT_SECRET",
    "DNA_API_APPKEY",
    "SENTRY_DSN",
    "SNOWFLAKE_PASSWORD",
    "USER_SERVICE_CLIENT_SECRET",
  ]

  dna_api_common_secrets = {}

  dna_api_secrets_mapping = [
    for k, v in merge(aws_secretsmanager_secret.dna_api_secret, local.dna_api_common_secrets) :
    {
      name      = k,
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${v["name"]}"
    }
  ]

  dna_api_secrets_combined = concat(local.dna_api_secrets_mapping, [
    {
      name      = "POSTGRES_PASSWORD",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/main/pg/user:password::"
    },
    {
      name      = "POSTGRES_USER",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/main/pg/user:username::"
    },
    {
      name      = "POSTGRES_HOST",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/main/pg/user:host::"
    },
    {
      name      = "POSTGRES_PORT",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/main/pg/user:port::"
    },
    {
      name      = "POSTGRES_DATA_PASSWORD",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/aggregates/pg/user:password::"
    },
    {
      name      = "POSTGRES_DATA_USER",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/aggregates/pg/user:username::"
    },
    {
      name      = "POSTGRES_DATA_HOST",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/aggregates/pg/user:host::"
    },
    {
      name      = "POSTGRES_DATA_PORT",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/aggregates/pg/user:port::"
    },
  ])

  dna_api_env_vars = [
    {
      name  = "DEBUG",
      value = ""
    },
    {
      name  = "ENVIRONMENT",
      value = local.environment
    },
    {
      name  = "SNOWFLAKE_DRIVER",
      value = "snowflake"
    },
    {
      name  = "SNOWFLAKE_USER",
      value = "DNA_USER"
    },
    {
      name  = "SNOWFLAKE_ACCOUNT",
      value = "delphi.us-east-1"
    },
    {
      name  = "SNOWFLAKE_WAREHOUSE",
      value = "DNA_WH"
    },
    {
      name  = "SNOWFLAKE_DATABASE",
      value = "DELPHI_EXPLORATION"
    },
    {
      name  = "SNOWFLAKE_HOST",
      value = "delphi.us-east-1.snowflakecomputing.com"
    },
    {
      name  = "SNOWFLAKE_PORT",
      value = 443
    },
    {
      name  = "SNOWFLAKE_SCHEMA",
      value = "CHARTMETRIC"
    },
    {
      name  = "ATLAS_BASE_URL",
      value = "https://${module.atlas_domains.prod["atlas-um"]}/"
    },
    {
      name  = "ATLAS_AUDIENCE",
      value = "atlasum|api_read"
    },
    {
      name  = "ATLAS_CLIENT_ID",
      value = "5e196cdb-d8a9-402b-befa-2dc4b80eaf9d"
    },
    {
      name  = "POSTGRES_DB",
      value = "main_${local.env_prefix}"
    },
    {
      name  = "POSTGRES_SCHEMA",
      value = "dna"
    },
    {
      name  = "POSTGRES_DATA_DB",
      value = "non_signed_aggregates_${local.env_prefix}"
    },
    {
      name  = "POSTGRES_DATA_SCHEMA",
      value = "dna"
    },
    {
      name  = "SNOWFLAKE_ENV",
      value = upper(local.env_prefix)
    },
    {
      name  = "IMAGE_SERVICE_URL",
      value = "https://${module.atlas_domains.prod["images-api"]}"
    },
    {
      name  = "ELASTIC_SEARCH_URL",
      value = "https://${data.aws_elasticsearch_domain.main.endpoint}"
    },
    {
      name  = "ELASTIC_SEARCH_ENV",
      value = upper(local.env_prefix)
    },
    {
      name  = "USER_SERVICE_AUDIENCE",
      value = "apollo|api"
    },
    {
      name  = "USER_SERVICE_BASE_URL",
      value = "https://proxy.apollo.stream/user-data-api/"
    },
    {
      name  = "USER_SERVICE_CLIENT_ID",
      value = "4a9829f7-2973-4951-8e8a-182734f30182"
    },
  ]
}

data "aws_ecr_repository" "dna_api_ecr" {
  name = "dna/api"

  provider = aws.gdb-whitelist-dev
}

data "aws_ecr_repository" "dna_api_db_migrations_ecr" {
  name = "dna/api-db-migrations"

  provider = aws.gdb-whitelist-dev
}

data "aws_secretsmanager_secret_version" "dna_api_auth_key" {
  secret_id = "${local.secrets_name_prefix}/api/DNA_API_APPKEY"
}

resource "aws_secretsmanager_secret" "dna_api_secret" {
  for_each = toset(local.dna_api_secrets_list)

  name       = "${local.secrets_name_prefix}/api/${each.value}"
  kms_key_id = data.aws_kms_key.secrets_general_key.id

  tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Secrets Manager",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_SCRT"
    }
  )
}

module "dna_api_task_def" {
  source = "../../../modules/ecs/tasks/fargate_v3"

  env_prefix      = local.env_prefix
  project_group   = local.project_group
  family          = "${local.env_prefix}-${local.project_group}-api"
  container_name  = "api"
  container_image = "${data.aws_ecr_repository.dna_api_ecr.repository_url}:${local.docker_image_env_tag[local.env_prefix]}"
  cpu             = 1024
  memory          = 2048

  healthcheck = {
    command     = ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
    retries     = 3
    timeout     = 5
    interval    = 30
    startPeriod = 5
  }

  datadog_enabled    = true
  dd_apm_enabled     = true
  dd_logs_injection  = false
  dd_container_image = "public.ecr.aws/datadog/agent:latest"
  dd_awslogs_group   = aws_cloudwatch_log_group.datadog_agent.name

  awslogs_retention = module.cloudwatch_logs_retention_by_env[local.env_prefix]

  task_role_arn = data.aws_iam_role.standard_exec.arn
  exec_role_arn = data.aws_iam_role.standard_exec.arn

  env_vars = local.dna_api_env_vars
  secrets  = local.dna_api_secrets_combined

  port_mappings = [
    {
      containerPort = 8000
      hostPort      = 8000
      protocol      = "tcp"
    }
  ]

  docker_labels = {
    "traefik.enable" = "true"

    "traefik.http.services.whitelist-api.loadBalancer.server.port"          = "8000"
    "traefik.http.services.whitelist-api.loadBalancer.server.scheme"        = "http"
    "traefik.http.services.whitelist-api.loadBalancer.healthCheck.interval" = "30s"
    "traefik.http.services.whitelist-api.loadBalancer.healthCheck.path"     = "/health"
    "traefik.http.services.whitelist-api.loadBalancer.healthCheck.port"     = "8000"
    "traefik.http.services.whitelist-api.loadBalancer.healthCheck.scheme"   = "http"
    "traefik.http.services.whitelist-api.loadBalancer.healthCheck.timeout"  = "5s"

    // request via traefik
    "traefik.http.routers.whitelist-api.rule"        = "Host(`${module.domains[local.env_prefix]["traefik"]}`) && PathPrefix(`/api`)"
    "traefik.http.routers.whitelist-api.entryPoints" = "web"
    "traefik.http.routers.whitelist-api.service"     = "whitelist-api"
    "traefik.http.routers.whitelist-api.middlewares" = join(",", [
      "whitelist-api-cors@ecs",
      "whitelist-api-gzip@ecs",
      "whitelist-api-auth@ecs",
      "whitelist-api-addAuthHeader@ecs",
    ])

    // requests via traefik without auth
    "traefik.http.routers.whitelist-api-noAuth.rule"        = "Host(`${module.domains[local.env_prefix]["traefik"]}`) && PathPrefix(`/api/doc/`, `/static`, `/api/docs/`)"
    "traefik.http.routers.whitelist-api-noAuth.entryPoints" = "web"
    "traefik.http.routers.whitelist-api-noAuth.service"     = "whitelist-api"
    "traefik.http.routers.whitelist-api-noAuth.middlewares" = join(",", [
      "whitelist-api-cors@ecs",
      "whitelist-api-gzip@ecs",
    ])

    "traefik.http.middlewares.whitelist-api-auth.forwardAuth.address"             = "https://${module.domains[local.env_prefix]["auth-api"]}/authorize"
    "traefik.http.middlewares.whitelist-api-auth.forwardAuth.trustForwardHeader"  = "true"
    "traefik.http.middlewares.whitelist-api-auth.forwardAuth.authResponseHeaders" = "X-User-Id,X-Userinfo"

    "traefik.http.middlewares.whitelist-api-addAuthHeader.headers.customRequestHeaders.Authorization" = data.aws_secretsmanager_secret_version.dna_api_auth_key.secret_string

    "traefik.http.middlewares.whitelist-api-cors.headers.accessControlAllowMethods" = "GET,PUT,POST"
    "traefik.http.middlewares.whitelist-api-cors.headers.accessControlAllowOriginList" = join(",",
      concat(
        formatlist("https://%s", [
          module.domains[local.env_prefix]["web"],
          "localhost:4000",
          "local.dna.stream:4000",
          ]
        ),
        formatlist("http://%s", [
          "localhost:4000",
          "local.dna.stream:4000",
          ]
        ),
      )
    )
    "traefik.http.middlewares.whitelist-api-cors.headers.accessControlMaxAge" = "600"
    "traefik.http.middlewares.whitelist-api-cors.headers.addVaryHeader"       = "true"

    "traefik.http.middlewares.whitelist-api-gzip.compress" = "true"

    // direct requests
    "traefik.http.routers.whitelist-api-internal.rule"        = "Host(`${module.domains[local.env_prefix]["api"]}`)"
    "traefik.http.routers.whitelist-api-internal.entryPoints" = "web"
    "traefik.http.routers.whitelist-api-internal.service"     = "whitelist-api"
    "traefik.http.routers.whitelist-api-internal.middlewares" = "whitelist-api-gzip@ecs"
  }

  dd_secrets = [
    {
      name      = "DD_API_KEY",
      valueFrom = "arn:aws:secretsmanager:us-east-1:${local.account_id}:secret:whitelist/${local.env_prefix}/common/DD_API_KEY"
    }
  ]

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Portal",
      service                  = "ECS",
      plat_env_project_service = "${local.aggregated_tag}_PRL_ECS"
    }
  )
}

module "dna_api_service" {
  source = "../../../modules/ecs/services/service_taskless_v2"

  env_prefix    = local.env_prefix
  project       = "api"
  project_group = local.project_group

  cluster_arn   = data.aws_ecs_cluster.main.arn
  desired_count = 2

  security_groups = [data.aws_security_group.ecs.id]
  subnets         = data.aws_subnets.private_subnets.ids
  vpc_id          = data.aws_vpc.main.id

  task_definition_arn = module.dna_api_task_def.arn

  enable_ecs_managed_tags = true

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Portal",
      service                  = "ECS",
      plat_env_project_service = "${local.aggregated_tag}_PRL_ECS"
    }
  )
}

module "dna_api_appautoscaling" {
  source = "../../../modules/appautoscaling/ecs"

  env_prefix           = local.env_prefix
  max_capacity         = 10
  min_capacity         = 2
  project              = "api"
  project_group        = local.project_group
  resource_id          = "service/${data.aws_ecs_cluster.main.cluster_name}/${module.dna_api_service.ecs_service.name}"
  upscaling_adjustment = 1
}

resource "aws_cloudwatch_metric_alarm" "dna_api_high_usage" {
  alarm_name          = "${local.name_prefix}-dna-api_high_usage"
  alarm_description   = "Memory/CPU usage is higher than threshold."
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  threshold           = 1
  actions_enabled     = true
  alarm_actions       = [module.dna_api_appautoscaling.scaling_up_policy.arn]

  metric_query {
    id          = "check_thresholds"
    expression  = "(cpu >= 30 OR memory >= 15)"
    label       = "CPU and Memory utilization limits"
    return_data = true
  }

  metric_query {
    id          = "cpu"
    return_data = false

    metric {
      metric_name = "CPUUtilization"
      namespace   = "AWS/ECS"
      period      = "60"
      stat        = "Average"

      dimensions = {
        ClusterName = data.aws_ecs_cluster.main.cluster_name
        ServiceName = module.dna_api_service.ecs_service.name
      }
    }
  }

  metric_query {
    id          = "memory"
    return_data = false

    metric {
      metric_name = "MemoryUtilization"
      namespace   = "AWS/ECS"
      period      = "60"
      stat        = "Average"

      dimensions = {
        ClusterName = data.aws_ecs_cluster.main.cluster_name
        ServiceName = module.dna_api_service.ecs_service.name
      }
    }
  }
}

resource "aws_cloudwatch_metric_alarm" "dna_api_low_usage" {
  alarm_name          = "${local.name_prefix}-dna-api_low_usage"
  alarm_description   = "Memory/CPU usage is lower than threshold."
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 3
  threshold           = 1
  actions_enabled     = true
  alarm_actions       = [module.dna_api_appautoscaling.scaling_down_policy.arn]

  metric_query {
    id          = "check_thresholds"
    expression  = "(cpu < 30 AND memory < 15)"
    label       = "CPU and Memory utilization limits"
    return_data = true
  }

  metric_query {
    id          = "cpu"
    return_data = false

    metric {
      metric_name = "CPUUtilization"
      namespace   = "AWS/ECS"
      period      = "180"
      stat        = "Average"

      dimensions = {
        ClusterName = data.aws_ecs_cluster.main.cluster_name
        ServiceName = module.dna_api_service.ecs_service.name
      }
    }
  }

  metric_query {
    id          = "memory"
    return_data = false

    metric {
      metric_name = "MemoryUtilization"
      namespace   = "AWS/ECS"
      period      = "180"
      stat        = "Average"

      dimensions = {
        ClusterName = data.aws_ecs_cluster.main.cluster_name
        ServiceName = module.dna_api_service.ecs_service.name
      }
    }
  }
}

module "dna_api_db_migrations_task_def" {
  source = "../../../modules/ecs/tasks/fargate_v3"

  env_prefix      = local.env_prefix
  project_group   = local.project_group
  family          = "${local.env_prefix}-${local.project_group}-api_db_migrations"
  container_name  = "api-db-migrations"
  container_image = "${data.aws_ecr_repository.dna_api_db_migrations_ecr.repository_url}:${local.docker_image_env_tag[local.env_prefix]}"
  cpu             = 512
  memory          = 1024

  awslogs_retention = module.cloudwatch_logs_retention_by_env[local.env_prefix]

  task_role_arn = data.aws_iam_role.standard_exec.arn
  exec_role_arn = data.aws_iam_role.standard_exec.arn

  env_vars = [
    {
      name  = "POSTGRES_DB",
      value = "main_${local.env_prefix}"
    },
  ]
  secrets = [
    {
      name      = "POSTGRES_PASSWORD",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.project_group}/${local.env_prefix}/main_owner:password::"
    },
    {
      name      = "POSTGRES_USER",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.project_group}/${local.env_prefix}/main_owner:username::"
    },
    {
      name      = "POSTGRES_HOST",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.project_group}/${local.env_prefix}/main_owner:host::"
    },
    {
      name      = "POSTGRES_PORT",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.project_group}/${local.env_prefix}/main_owner:port::"
    }
  ]

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Portal",
      service                  = "ECS",
      plat_env_project_service = "${local.aggregated_tag}_PRL_ECS"
    }
  )
}
*/
