locals {
  images_api_secrets_list = [
    "APPLE_MUSIC_KEY_ID",
    "APPLE_MUSIC_SECRET_KEY",
    "APPLE_MUSIC_TEAM_ID",
    "AUTH0_MANAGEMENT_CLIENT_SECRET",
    "SCUBA_API_KEY",
    "SENTRY_DSN",
    "SPOTIFY_CLIENT_ID",
    "SPOTIFY_CLIENT_SECRET",
    "X_API_KEY",
  ]

  images_api_secrets_mapping = [
    for k, v in aws_secretsmanager_secret.images_api_secret :
    {
      name      = k,
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${v["name"]}"
    }
  ]

  images_api_secrets_combined = concat(
    local.images_api_secrets_mapping,
    [
      {
        name      = "DB_PASS",
        valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/images/pg/user:password::"
      },
      {
        name      = "DB_USER",
        valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/images/pg/user:username::"
      },
      {
        name      = "DB_HOST",
        valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.project_group}/${local.env_prefix}/images/pg/user:host::"
      },
    ]
  )

  images_api_db_migrations_secrets_combined = concat(
    local.images_api_secrets_mapping,
    [
      {
        name      = "DB_PASS",
        valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.secrets_name_prefix}/images_owner:password::"
      },
      {
        name      = "DB_USER",
        valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.secrets_name_prefix}/images_owner:username::"
      },
      {
        name      = "DB_HOST",
        valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:maintenance/common/${local.secrets_name_prefix}/images_owner:host::"
      },
    ]
  )

  images_api_env_vars = [
    {
      name  = "DJANGO_ENVIRONMENT",
      value = local.environment
    },
    {
      name  = "SME_PROXY",
      value = "10.12.249.5"
    },
    {
      name  = "SPOTIFY_DEFAULT_IMAGE_URL",
      value = "https://prod.smedx.net/imd-service/images/icons_SMELogo_300x300.jpg"
    },
    {
      name  = "IMD_BASE_PATH",
      value = "/imd-service/api"
    },
    {
      name  = "DX_HOST",
      value = "prod.smedx.net"
    },
    {
      name  = "DX_DEFAULT_ARTIST_IMAGE",
      value = "https://prod.smedx.net/dxWeb/img/icons/artist75x75.jpg"
    },
    {
      name  = "PORT",
      value = 8000
    },
    {
      name  = "AUTH0_MANAGEMENT_CLIENT_ID",
      value = "uJyvmAvj7z9lQcYEu48TD8LlZZcWTmOs"
    },
    {
      name  = "AUTH0_DOMAIN",
      value = "prod-dna-apps.auth0.com"
    },
    {
      name  = "VENDOR_API_HOST",
      value = module.apollo_domains.prod["traefik"]
    },
    {
      name  = "SCUBA_API_HOST",
      value = "api-scubaassets.scuba.tools"
    },
    {
      name  = "REDIS_URL",
      value = "rediss://${data.aws_elasticache_replication_group.images_api_cache.primary_endpoint_address}:${data.aws_elasticache_replication_group.images_api_cache.port}/0?ssl_cert_reqs=none"
    },
    {
      name  = "CELERY_BROKER_URL",
      value = "rediss://${data.aws_elasticache_replication_group.images_api_cache.primary_endpoint_address}:${data.aws_elasticache_replication_group.images_api_cache.port}/1?ssl_cert_reqs=none"
    },
    {
      name  = "CELERY_RESULT_BACKEND",
      value = "rediss://${data.aws_elasticache_replication_group.images_api_cache.primary_endpoint_address}:${data.aws_elasticache_replication_group.images_api_cache.port}/1?ssl_cert_reqs=none"
    },
    {
      name  = "DB_NAME",
      value = "images_${local.env_prefix}"
    },
    {
      name  = "ATLAS_LOGIN_URL",
      value = "https://um.atlas.stream/usm/login"
    },
    {
      name  = "ATLAS_LOGOUT_URL",
      value = "https://um.atlas.stream/usm/logout"
    },
    {
      name  = "ATLAS_PUBLIC_KEY_URL",
      value = "https://static-um.atlas.stream/pem/public.pem"
    },
    {
      name  = "ATLAS_REFRESH_TOKEN_URL",
      value = "https://${module.domains[local.env_prefix]["atlas-um"]}/usm/token/refresh"
    },
    {
      name  = "CLOUDFRONT_DISTRIBUTION_ID",
      value = aws_cloudfront_distribution.images_api.id
    },
    {
      name = "ALLOWED_HOSTS",
      value = join(",",
        [
          module.domains[local.env_prefix]["images-api"],
        ]
      )
    },
    {
      name  = "AWS_STORAGE_BUCKET_NAME",
      value = module.images_api_uploaded_files.bucket.bucket
    },
    {
      name  = "AWS_S3_CUSTOM_DOMAIN",
      value = module.domains[local.env_prefix]["images-api"]
    },
    {
      name  = "AWS_S3_URL_PROTOCOL",
      value = "https://"
    },
  ]
}

data "aws_ecr_repository" "images_api" {
  name = "${local.project_group}/core-images"

  provider = aws.gdb-core-dev
}

resource "aws_secretsmanager_secret" "images_api_secret" {
  for_each = toset(local.images_api_secrets_list)

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

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

module "images_api_ecs_role" {
  source = "../../../../modules/iam/roles/ecs_task_role"

  enable_default_role = false
  name_prefix         = local.name_prefix
  name                = "images_api_ecs_role"

  policies_list = [
    data.aws_iam_policy.logging_policy.arn,
    data.aws_iam_policy.secrets_deployment_ro.arn,
    aws_iam_policy.cloudfront_cache_invalidate_policy.arn,
    module.images_api_uploads_bucket_rw.policy.arn,
  ]

  common_tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }
}

module "images_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}-images-api"
  container_name  = "images-api"
  container_image = "${data.aws_ecr_repository.images_api.repository_url}:${local.docker_image_env_tag[local.env_prefix]}"
  cpu             = 1024
  memory          = 2048

  awslogs_retention = module.cloudwatch_logs_retention_by_env[local.env_prefix]

  task_role_arn = module.images_api_ecs_role.role.arn
  exec_role_arn = data.aws_iam_role.standard_exec.arn

  env_vars = local.images_api_env_vars
  secrets  = local.images_api_secrets_combined

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

  dd_secrets = [
    {
      name      = "DD_API_KEY",
      valueFrom = "arn:aws:secretsmanager:${var.aws_region_id}:${local.account_id}:secret:${local.secrets_name_prefix}/common/DD_API_KEY"
    }
  ]

  dd_env_vars = [
    {
      name  = "DD_APM_IGNORE_RESOURCES",
      value = "GET /health"
    },
    {
      name  = "DD_TAGS",
      value = "service:core-images-api application_family:atlas"
    },
  ]

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

  common_tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }
}

module "main_one_time_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}-images-api-one-time"
  container_name       = "images-api"
  container_image      = "${data.aws_ecr_repository.images_api.repository_url}:${local.docker_image_env_tag[local.env_prefix]}"
  cpu                  = 512
  memory               = 1024
  awslogs_create_group = false

  command = []

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

  env_vars = local.images_api_env_vars
  secrets  = local.images_api_db_migrations_secrets_combined

  common_tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }
}

resource "aws_ecs_service" "main" {
  name             = "${local.name_prefix}-images-api"
  cluster          = data.aws_ecs_cluster.main.arn
  task_definition  = module.images_api_task_def.arn
  launch_type      = "FARGATE"
  platform_version = "1.4.0"

  desired_count                      = 1
  deployment_minimum_healthy_percent = 100
  deployment_maximum_percent         = 200

  load_balancer {
    target_group_arn = aws_lb_target_group.main.arn
    container_name   = "images-api"
    container_port   = 8000
  }

  network_configuration {
    subnets          = data.aws_subnets.private_subnets.ids
    security_groups  = [data.aws_security_group.ecs.id]
    assign_public_ip = false
  }

  enable_ecs_managed_tags = true
  propagate_tags          = "TASK_DEFINITION"

  tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }

  wait_for_steady_state = true

  lifecycle {
    ignore_changes = [desired_count]
  }
}

module "images_api_appautoscaling" {
  source        = "../../../../modules/appautoscaling/ecs"
  env_prefix    = local.env_prefix
  max_capacity  = 10
  min_capacity  = 2
  project       = "images-api"
  project_group = local.project_group
  resource_id   = "service/${data.aws_ecs_cluster.main.cluster_name}/${aws_ecs_service.main.name}"
}

resource "aws_cloudwatch_log_group" "main_celery_log_group" {
  name              = "/ecs/${local.name_prefix}-images-api-celery"
  retention_in_days = module.cloudwatch_logs_retention_by_env[local.env_prefix]

  tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }
}

module "main_celery_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}-images-api-celery"
  container_name  = "images-api-celery"
  container_image = "${data.aws_ecr_repository.images_api.repository_url}:${local.docker_image_env_tag[local.env_prefix]}"
  cpu             = 1024
  memory          = 2048

  awslogs_create_group = false
  awslogs_group_name   = aws_cloudwatch_log_group.main_celery_log_group.name

  entrypoint = ["/opt/venv/bin/celery", "-A", "core_images", "worker", "--loglevel=info"]

  task_role_arn = module.images_api_ecs_role.role.arn
  exec_role_arn = data.aws_iam_role.standard_exec.arn

  env_vars = local.images_api_env_vars
  secrets  = local.images_api_secrets_combined

  common_tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }
}

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

  env_prefix    = local.env_prefix
  project       = "images-api-celery"
  project_group = local.project_group

  cluster_arn   = data.aws_ecs_cluster.main.arn
  desired_count = 0
  min_percent   = 0
  max_percent   = 100

  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.main_celery_task_def.arn

  enable_ecs_managed_tags = true

  common_tags = {
    project                  = "IMAGES",
    service                  = "ECS",
    plat_env_project_service = "${local.aggregated_tag}_IMG_ECS"
  }
}
