resource "aws_ecs_cluster" "main" {
  name = "${local.name_prefix}-cluster"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

resource "aws_cloudwatch_log_group" "control" {
  name              = "/aws/ecs/${local.name_prefix}-control"
  retention_in_days = 30
}

resource "aws_cloudwatch_log_group" "plane" {
  name              = "/aws/ecs/${local.name_prefix}-plane"
  retention_in_days = 30
}

locals {
  # When ECR repos are created in-stack (legacy flow), fall back to a `:bootstrap`
  # tag against the local repo URI if the caller didn't set var.control_image yet.
  # When ECR repos are owned by `aries infra images` instead (new flow), the caller
  # MUST set var.control_image / var.plane_image — empty falls through and Fargate
  # will refuse to launch a task with no image.
  control_image = (
    length(var.control_image) > 0 ? var.control_image :
    var.create_ecr_repos ? "${aws_ecr_repository.control[0].repository_url}:bootstrap" :
    ""
  )
  plane_image = (
    length(var.plane_image) > 0 ? var.plane_image :
    var.create_ecr_repos ? "${aws_ecr_repository.plane[0].repository_url}:bootstrap" :
    ""
  )

  control_origin_url = local.has_domain ? "https://${local.data_fqdn}" : "http://${aws_lb.main.dns_name}/plane"
}

resource "aws_ecs_task_definition" "control" {
  family                   = "${local.name_prefix}-control"
  cpu                      = var.control_task_cpu
  memory                   = var.control_task_memory
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  execution_role_arn       = aws_iam_role.task_execution.arn
  task_role_arn            = aws_iam_role.control_task.arn

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

  container_definitions = jsonencode([{
    name      = "control"
    image     = local.control_image
    essential = true

    portMappings = [{
      containerPort = 8787
      protocol      = "tcp"
    }]

    environment = [
      { name = "STORE", value = "postgres" },
      { name = "PORT", value = "8787" },
      { name = "HOST", value = "0.0.0.0" },
      { name = "DATALAKE_ORIGIN_URL", value = local.control_origin_url },
      { name = "LOG_LEVEL", value = "info" },
      { name = "CONTROL_VERSION", value = "0.1.0" },
    ]

    secrets = [
      { name = "DATABASE_URL", valueFrom = aws_secretsmanager_secret.database_url.arn },
      { name = "TOKEN_SIGNING_SECRET", valueFrom = aws_secretsmanager_secret.token_signing.arn },
    ]

    logConfiguration = {
      logDriver = "awslogs"
      options = {
        "awslogs-group"         = aws_cloudwatch_log_group.control.name
        "awslogs-region"        = var.region
        "awslogs-stream-prefix" = "control"
      }
    }
  }])
}

resource "aws_ecs_task_definition" "plane" {
  family                   = "${local.name_prefix}-plane"
  cpu                      = var.plane_task_cpu
  memory                   = var.plane_task_memory
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  execution_role_arn       = aws_iam_role.task_execution.arn
  task_role_arn            = aws_iam_role.plane_task.arn

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

  container_definitions = jsonencode([{
    name      = "plane"
    image     = local.plane_image
    essential = true

    portMappings = [{
      containerPort = 8788
      protocol      = "tcp"
    }]

    environment = [
      { name = "CONTROL_STORE", value = "postgres" },
      { name = "PAYLOAD_STORE", value = "postgres" },
      { name = "PORT", value = "8788" },
      { name = "HOST", value = "0.0.0.0" },
      { name = "AWS_REGION", value = var.region },
      { name = "PAYLOAD_S3_BUCKET", value = aws_s3_bucket.payloads.bucket },
      { name = "DATALAKE_ROUTE_PREFIX", value = local.has_domain ? "" : "/plane" },
      { name = "LOG_LEVEL", value = "info" },
      { name = "PLANE_VERSION", value = "0.1.0" },
    ]

    secrets = [
      { name = "DATABASE_URL", valueFrom = aws_secretsmanager_secret.database_url.arn },
      { name = "TOKEN_SIGNING_SECRET", valueFrom = aws_secretsmanager_secret.token_signing.arn },
    ]

    logConfiguration = {
      logDriver = "awslogs"
      options = {
        "awslogs-group"         = aws_cloudwatch_log_group.plane.name
        "awslogs-region"        = var.region
        "awslogs-stream-prefix" = "plane"
      }
    }
  }])
}

resource "aws_ecs_service" "control" {
  name            = "${local.name_prefix}-control"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.control.arn
  desired_count   = var.control_desired_count
  launch_type     = "FARGATE"
  propagate_tags  = "SERVICE"

  network_configuration {
    subnets          = [for s in aws_subnet.private : s.id]
    security_groups  = [aws_security_group.service.id]
    assign_public_ip = false
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.control.arn
    container_name   = "control"
    container_port   = 8787
  }

  deployment_minimum_healthy_percent = 50
  deployment_maximum_percent         = 200

  lifecycle {
    ignore_changes = [desired_count]
  }

  depends_on = [aws_lb_listener.http]
}

resource "aws_ecs_service" "plane" {
  name            = "${local.name_prefix}-plane"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.plane.arn
  desired_count   = var.plane_desired_count
  launch_type     = "FARGATE"
  propagate_tags  = "SERVICE"

  network_configuration {
    subnets          = [for s in aws_subnet.private : s.id]
    security_groups  = [aws_security_group.service.id]
    assign_public_ip = false
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.plane.arn
    container_name   = "plane"
    container_port   = 8788
  }

  deployment_minimum_healthy_percent = 50
  deployment_maximum_percent         = 200

  lifecycle {
    ignore_changes = [desired_count]
  }

  depends_on = [aws_lb_listener.http]
}
