// Provisioned in shared module
data "aws_security_group" "lb_backend" {
  name = var.lb_backend_security_group_name
}

data "aws_elasticache_replication_group" "main_cache" {
  replication_group_id = var.main_cache_replication_group_id
}

resource "aws_security_group" "backend" {
  name        = "backend-${var.stage}"
  description = "Allow Inbound traffic from ${var.lb_backend_security_group_name} Security Group"
  vpc_id      = var.aws_vpc_id

  ingress {
    from_port       = 3000
    to_port         = 3001
    protocol        = "tcp"
    security_groups = [data.aws_security_group.lb_backend.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_ecs_task_definition" "backend" {
  family                   = "backend-${var.stage}"
  requires_compatibilities = ["FARGATE"]

	skip_destroy = true

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

  network_mode       = "awsvpc"
  execution_role_arn = var.execution_role_arn
  cpu                = 256
  memory             = 1024

  container_definitions = jsonencode(
    [
      {
        name      = "log_router",
        image     = "amazon/aws-for-fluent-bit:stable",
        essential = true,
        firelensConfiguration = {
          type = "fluentbit",
          options = {
            enable-ecs-log-metadata = "true",
            config-file-type        = "file",
            config-file-value       = "/fluent-bit/configs/output-metrics-healthcheck.conf"
          }
        },
        healthCheck = {
          command     = ["CMD-SHELL", "curl -f http://127.0.0.1:2020/api/v1/health || exit 1"],
          startPeriod = 30
          interval    = 30,
          timeout     = 5,
          retries     = 3,
        },
      },
      {
        name      = "datadog-agent",
        image     = "datadog/agent:latest",
        essential = true,
        portMappings = [
          { containerPort = 8126, protocol = "tcp" },
          { containerPort = 8125, protocol = "udp" }
        ],
        environment = [
          { name = "DD_API_KEY", value = var.datadog_api_key },
          { name = "DD_SITE", value = var.datadog_site },
          { name = "ECS_FARGATE", value = "true" },
          { name = "DD_APM_ENABLED", value = "true" },
          { name = "DD_APM_NON_LOCAL_TRAFFIC", value = "true" },
          { name = "DD_RUNTIME_SECURITY_CONFIG_ENABLED", value = "true" },
          { name = "DD_RUNTIME_SECURITY_CONFIG_EBPFLESS_ENABLED", value = "true" },
        ],
        healthCheck = {
          command     = ["CMD-SHELL", "/probe.sh"],
          startPeriod = 60
          interval    = 30,
          timeout     = 5,
          retries     = 3,
        },
      },
      {
        name      = "backend"
        image     = format("%s%s", var.repository_url, ":latest")
        essential = true
        portMappings = [
          {
            name          = "http"
            containerPort = 3000
            hostPort      = 3000
            protocol      = "tcp"
            appProtocol   = "http"
          },
          {
            name          = "ws"
            containerPort = 3001
            hostPort      = 3001
            protocol      = "tcp"
            appProtocol   = "http"
          }
        ]
        environment = [
          { name = "NODE_ENV", value = "production" },
          { name = "APP_MODE", value = var.stage },
          { name = "DD_PROFILING_ENABLED", value = "true" },
          { name = "DD_RUNTIME_METRICS_ENABLED", value = "true" },
          { name = "DD_AGENT_HOST", value = "localhost" },
          { name = "DD_TRACE_AGENT_PORT", value = "8126" },
          { name = "DD_STATSD_HOST", value = "localhost" },
          { name = "DD_STATSD_PORT", value = "8125" },
          { name = "AWS_REGION", value = var.aws_region },
          { name = "AWS_ACCESS_KEY", value = var.aws_access_key },
          { name = "AWS_SECRET_KEY", value = var.aws_secret_key },
          { name = "AWS_S3_PUBLIC_BUCKET", value = var.public_bucket_name },
          { name = "DATABASE_HOST", value = var.db_address },
          { name = "DATABASE_PORT", value = tostring(var.db_port) },
          { name = "DATABASE_USERNAME", value = var.postgres_username },
          { name = "DATABASE_PASSWORD", value = var.postgres_password },
          { name = "DATABASE_NAME", value = var.postgres_database },
          { name = "DB_TIMEOUT", value = "30000" },
          { name = "REDIS_HOST", value = data.aws_elasticache_replication_group.main_cache.primary_endpoint_address },
          { name = "REDIS_PORT", value = tostring(data.aws_elasticache_replication_group.main_cache.port) },
          { name = "REDIS_DB", value = tostring(var.redis_db) },
          { name = "STRIPE_API_KEY", value = var.stripe.api_key },
          { name = "STRIPE_WEBHOOK_SECRET", value = var.stripe.webhook_secret },
          { name = "FROM_EMAIL", value : var.from_email },
          { name = "DASHBOARD_URL", value : "https://dashboard.${var.domain}" },
          { name = "CUSTOMER_APP_URL", value : "https://app.${var.domain}" },
          { name = "FIREBASE", value : var.firebase },
          { name = "GOOGLE_MAPS_API_KEY", value : var.google.maps_api_key },
          { name = "GOOGLE_ACTION_CENTER_PARTNER_ID", value : var.google.action_center.partner_id },
          { name = "GOOGLE_ACTION_CENTER_SERVICE_ACCOUNT_CLIENT_EMAIL", value : var.google.action_center.service_account.client_email },
          { name = "GOOGLE_ACTION_CENTER_SERVICE_ACCOUNT_PRIVATE_KEY", value : var.google.action_center.service_account.private_key },
          { name = "GOOGLE_ACTION_CENTER_BOOKING_SERVER_USERNAME", value : var.google.action_center.booking_server.username },
          { name = "GOOGLE_ACTION_CENTER_BOOKING_SERVER_PASSWORD", value : var.google.action_center.booking_server.password },
          { name = "GOOGLE_ACTION_CENTER_FEEDS_SFTP_KEY", value : var.google.action_center.feeds.sftp_key },
          { name = "GOOGLE_ACTION_CENTER_FEEDS_URL", value : var.google.action_center.feeds.url },
          { name = "GOOGLE_ACTION_CENTER_FEEDS_PORT", value : var.google.action_center.feeds.port },
          { name = "GOOGLE_ACTION_CENTER_FEEDS_USERNAMES_MERCHANTS", value : var.google.action_center.feeds.usernames.merchants },
          { name = "GOOGLE_ACTION_CENTER_FEEDS_USERNAMES_SERVICES", value : var.google.action_center.feeds.usernames.services },
          { name = "GOOGLE_ACTION_CENTER_FEEDS_USERNAMES_AVAILABILITY", value : var.google.action_center.feeds.usernames.availability },
        ],
        healthCheck = {
          command     = ["CMD-SHELL", "curl -f http://127.0.0.1:3000/api/health || exit 1"],
          startPeriod = 30
          interval    = 30,
          timeout     = 5,
          retries     = 3,
        },
        logConfiguration = {
          logDriver = "awsfirelens",
          options = {
            Name           = "datadog",
            apikey         = var.datadog_api_key,
            Host           = "http-intake.logs.datadoghq.eu",
            dd_service     = "backend",
            dd_source      = "aws",
            dd_message_key = "log",
            dd_tags        = "env:${var.stage}",
            TLS            = "on",
            provider       = "ecs"
          }
        },
        dependsOn = [
          { containerName = "datadog-agent", condition = "HEALTHY" }
        ]
      }
  ])

	lifecycle {
		// Terraform marks container_definitions as changed even without any changes
		// Removing this before apply when actual changes to container_definitions are applied
		# ignore_changes = [container_definitions]
	}
}

resource "aws_ecs_cluster" "backend" {
  name = "backend-${var.stage}"

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

resource "aws_ecs_service" "backend" {
  name                    = "backend"
  launch_type             = "FARGATE"
  cluster                 = aws_ecs_cluster.backend.arn
  task_definition         = aws_ecs_task_definition.backend.arn
  desired_count           = 1
  enable_ecs_managed_tags = true

  network_configuration {
    assign_public_ip = true
    security_groups  = [aws_security_group.backend.id]
    subnets          = [var.aws_subnets.a, var.aws_subnets.b]
  }

  deployment_circuit_breaker {
    enable   = true
    rollback = true
  }

  load_balancer {
    target_group_arn = var.http_target_group_arn
    container_name   = "backend"
    container_port   = 3000
  }

  load_balancer {
    target_group_arn = var.ws_target_group_arn
    container_name   = "backend"
    container_port   = 3001
  }
}
