data "aws_region" "current" {}

data "aws_msk_cluster" "msk_cluster" {
  cluster_name = "humand-aws-msk-cluster"
}

data "aws_sqs_queue" "humand_webhooks_external_queue" {
  name = "humand-webhooks-external.fifo"
}

data "aws_subnets" "humand" {
  filter {
    name   = "vpc-id"
    values = [var.humand_vpc_id]
  }
  filter {
    name   = "map-public-ip-on-launch"
    values = [false]
  }
}

data "aws_ecs_cluster" "ecs_cluster" {
  cluster_name = var.cluster_name
}

data "aws_sqs_queue" "marty_commands_queue" {
  name = "marty-commands.fifo"
}

data "aws_sqs_queue" "heimdall_content_queue" {
  name = "humand-heimdall-service-content.fifo"
}

# Data source to read outputs from aws-lambda-ses-event-handler infrastructure
data "terraform_remote_state" "ses_handler" {
  backend = "s3"

  config = {
    bucket = "humand-terraform-state-${var.env}"
    key    = "service/aws-lambda-ses-event-handler/terraform.tfstate"
    region = "us-east-1"
  }
}

# Data source to read outputs from learning-service infrastructure
data "terraform_remote_state" "learning_service" {
  backend = "s3"
  config = {
    bucket = "humand-terraform-state-${var.env}"
    key    = "service/humand-learning-service/terraform.tfstate"
    region = "us-east-1"
  }
}

data "terraform_remote_state" "janus" {
  backend = "s3"
  config = {
    bucket = "humand-terraform-state-${var.env}"
    key    = "service/humand-janus-service/terraform.tfstate"
    region = data.aws_region.current.name
  }
}

data "aws_ssm_parameter" "internal_grpc_lb_url" {
  name = "arn:aws:ssm:${data.aws_region.current.name}:${var.aws_account}:parameter/common/urls/api/grpc"
}

locals {
  # Fix inconsistency in naming for datadog env
  fixed_dd_env = replace(var.env, "slot", "_slot_")

  environment = merge({
    NODE_ENV                                 = "production"
    NEW_API_PATHS                            = false
    NEW_SSM_PATHS                            = true
    CLUSTER_DISABLED                         = "true"
    CLUSTER_MAX_SIZE                         = "1"
    NODE_OPTIONS                             = "--max-old-space-size=4096"
    ECS_CONTAINER_STOP_TIMEOUT               = "120"
    NODE_TYPE                                = var.node_type
    DD_ENV                                   = local.fixed_dd_env
    DD_APM_ENABLED                           = "true"
    DD_LOGS_INJECTION                        = true
    DD_PROFILING_ENABLED                     = true
    DD_REMOTE_CONFIG_ENABLED                 = "false"
    DD_SERVICE                               = var.service
    DD_SERVICE_MAPPING                       = "${var.service}-postgres:${var.service},${var.service}-redis:${var.service}"
    env                                      = var.env
    THREADS_TIME_OFF_DAILY_JOB               = 10
    AWS_SQS_MARTY_QUEUE_URL                  = data.aws_sqs_queue.marty_commands_queue.url
    AWS_SQS_HEIMDALL_CONTENT_QUEUE_URL       = data.aws_sqs_queue.heimdall_content_queue.url
    KAFKA_BROKERS                            = data.aws_msk_cluster.msk_cluster.bootstrap_brokers_sasl_iam
    AWS_SQS_WEBHOOKS_QUEUE_URL               = data.aws_sqs_queue.humand_webhooks_external_queue.url
    AWS_SQS_LEARNING_SCHEDULER_QUEUE_URL     = data.terraform_remote_state.learning_service.outputs.learning_scheduler_queue_url
    AWS_SQS_LEARNING_SCHEDULER_QUEUE_DLQ_ARN = data.terraform_remote_state.learning_service.outputs.learning_scheduler_queue_dlq_arn
    AWS_SQS_LEARNING_SCHEDULER_QUEUE_ARN     = data.terraform_remote_state.learning_service.outputs.learning_scheduler_queue_arn
    AWS_SQS_LEARNING_SCHEDULER_ROLE_ARN      = data.terraform_remote_state.learning_service.outputs.learning_scheduler_eventbridge_execution_role_arn
    AWS_SES_CONFIGURATION_SET                = data.terraform_remote_state.ses_handler.outputs.ses_configuration_set_name
    SESSIONS_CACHE_DB_HOST                   = data.terraform_remote_state.janus.outputs.sessions_redis_endpoint
    SESSIONS_CACHE_DB_PORT                   = tostring(data.terraform_remote_state.janus.outputs.sessions_redis_port)
    SESSIONS_CACHE_DB_USERNAME               = data.terraform_remote_state.janus.outputs.sessions_redis_rw_password_user_id
    JANUS_SERVICE_ADDRESS                    = data.aws_ssm_parameter.internal_grpc_lb_url.value
    NOTIFICATIONS_SERVICE_ADDRESS            = data.aws_ssm_parameter.internal_grpc_lb_url.value
    BAMBOO_SERVICE_ADDRESS                   = data.aws_ssm_parameter.internal_grpc_lb_url.value
    DESERT_EAGLE_SERVICE_ADDRESS             = data.aws_ssm_parameter.internal_grpc_lb_url.value
    CERBERUS_SERVICE_ADDRESS                 = data.aws_ssm_parameter.internal_grpc_lb_url.value
    SOCKETS_SERVICE_ADDRESS                  = data.aws_ssm_parameter.internal_grpc_lb_url.value
  }, var.environment_overrides)

  secrets = merge(local.ssm_secrets, var.secrets_overrides)

}

module "datadog" {
  source = "../datadog"

  service     = var.service
  aws_account = var.aws_account
  env         = local.fixed_dd_env
  dd_source   = "nodejs"
}

resource "aws_s3_object" "defaults_env" {
  bucket = "humand-config-${var.env}"
  key    = "dotenv/defaults/${var.service}.env"
  source = "${path.module}/env.default"
  etag   = filemd5("${path.module}/env.default")
}

module "ecs_service" {
  source      = "terraform-aws-modules/ecs/aws//modules/service"
  version     = "6.3.0"
  name        = var.service
  cluster_arn = data.aws_ecs_cluster.ecs_cluster.arn

  ignore_task_definition_changes = true

  cpu    = var.cpu
  memory = var.memory

  capacity_provider_strategy = {
    FARGATE = {
      capacity_provider = "FARGATE"
      weight            = var.fargate_weight
    },
    FARGATE_SPOT = {
      capacity_provider = "FARGATE_SPOT"
      weight            = var.fargate_spot_weight
    }
  }

  runtime_platform = {
    cpu_architecture        = "ARM64"
    operating_system_family = "LINUX"
  }

  track_latest = false

  create_task_exec_iam_role = false
  task_exec_iam_role_arn    = aws_iam_role.execution-role.arn
  tasks_iam_role_policies = merge(var.task_policies, {
    LoggingPolicy = module.datadog.logging_policy_arn
  })

  deployment_circuit_breaker = {
    enable   = true
    rollback = true
  }

  # Container definition(s)
  container_definitions = {
    humand-main-api = {
      cpu       = 0
      essential = true
      image     = var.docker_image

      tags = {
        Name = var.service
      }

      environmentFiles = [{
        value = aws_s3_object.defaults_env.arn
        type  = "s3"
        }
      ]

      environment = [
        for k, v in local.environment : {
          name  = k,
          value = v
        }
      ]

      secrets = [
        for k, v in local.secrets : {
          name      = k,
          valueFrom = v
        }
      ]

      portMappings = [
        {
          name          = var.service
          containerPort = 8080
          protocol      = "tcp"
        },
      ]
      dockerLabels = {
        "com.datadoghq.tags.service" = var.service,
        "com.datadoghq.tags.env"     = local.fixed_dd_env
      },

      healthCheck = {
        command = [
          "CMD-SHELL",
          "wget --spider -S http://localhost:8080/${var.healthcheck_path} 2>&1 | grep -E 'HTTP/1.1 200|HTTP/1.1 404' || exit 1"
        ],
        interval    = 30
        timeout     = 5
        retries     = 5
        startPeriod = 45
      }

      enable_cloudwatch_logging   = false
      create_cloudwatch_log_group = false
      logConfiguration            = module.datadog.log_configuration

      readonlyRootFilesystem = false
    }

    datadog-agent = module.datadog.sidecar_datadog-agent
    log-router    = module.datadog.sidecar_log-router
  }

  load_balancer = {
    service = {
      target_group_arn = var.ingress_lb_tg
      container_name   = "humand-main-api"
      container_port   = 8080
    }
  }

  enable_autoscaling = var.enable_autoscaling

  desired_count                      = var.autoscaling_min_capacity
  autoscaling_min_capacity           = var.autoscaling_min_capacity
  autoscaling_max_capacity           = var.autoscaling_max_capacity
  deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent
  deployment_maximum_percent         = var.deployment_maximum_percent

  autoscaling_policies = {
    cpu = {
      policy_type = "TargetTrackingScaling"
      target_tracking_scaling_policy_configuration = {
        predefined_metric_specification = {
          predefined_metric_type = "ECSServiceAverageCPUUtilization"
        }
        target_value       = var.cpu_target_utilization_percent
        scale_in_cooldown  = var.scale_in_cooldown
        scale_out_cooldown = var.scale_out_cooldown
      }
    }
  }

  subnet_ids = data.aws_subnets.humand.ids

  security_group_ingress_rules = {
    alb_ingress_3000 = {
      from_port   = 8080
      to_port     = 8080
      ip_protocol = "tcp"
      description = "Service port"
      cidr_ipv4   = var.cidr_block
    }
  }

  security_group_egress_rules = {
    egress_all = {
      ip_protocol = "-1"
      cidr_ipv4   = "0.0.0.0/0"
    }
  }

  autoscaling_scheduled_actions = var.autoscaling_scheduled_actions
}

moved {
  from = module.ecs_service.aws_ecs_service.this[0]
  to   = module.ecs_service.aws_ecs_service.ignore_task_definition[0]
}
