provider "aws" {
  region = var.aws_region

  default_tags {
    tags = module.default_tags.tags
  }
}

module "default_tags" {
  source             = "git@github.com:theorchard/terraform-default-tags.git//?ref=2.0.0"
  environment        = var.environment
  application_family = var.application_family
  service_name       = var.service_name
  team_name          = var.team_name
}

provider "aws" {
  region  = var.aws_region
  alias   = "networking"
  profile = "networking"

  default_tags {
    tags = module.default_tags_networking.tags
  }
}

module "default_tags_networking" {
  source             = "git@github.com:theorchard/terraform-default-tags.git//?ref=2.0.0"
  environment        = "networking"
  application_family = var.application_family
  service_name       = var.service_name
  team_name          = var.team_name
}

data "aws_caller_identity" "current" {}

data "aws_route53_zone" "route53_zone" {
  name = "${var.environment}.theorchard.io"

  provider = aws.networking
}

module "vpc_info" {
  source = "git@github.com:theorchard/terraform-vpc-info.git?ref=1.0.0"

  environment = var.environment
}

data "aws_acm_certificate" "theorchard_io" {
  domain   = "*.dev.theorchard.io"
  statuses = ["ISSUED"]
}

data "aws_wafv2_web_acl" "fargate_service_waf" {
  name  = "${var.environment}-orcd-waf-block"
  scope = "REGIONAL"
}

data "aws_route53_zone" "route53_zone" {
  name = "dev.theorchard.io"

  provider = aws.networking
}

resource "aws_security_group" "public_load_balancer_security_group" {
  name        = "${var.environment}-${var.service_name}-public-load-balancer-security-group"
  description = "Load balancer security group for ${var.environment}-${var.service_name}-public"
  vpc_id      = module.vpc_info.vpc_id
  ingress {
    description = "Allow inbound traffic from public IPs"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = var.public_allowed_ip_ranges
  }

  egress {
    from_port       = "8080"
    to_port         = "8080"
    protocol        = "tcp"
    security_groups = [module.ows_service_environment.fargate_security_group_id]
  }
}

resource "aws_lb" "public_application_load_balancer" {
  # checkov:skip=CKV2_AWS_20:We do not use HTTP to HTTPS redirect
  # checkov:skip=CKV2_AWS_76:False positive, possibly from using a data source for WAF
  name               = "${var.environment}-${var.service_name}-public-lb"
  internal           = false
  load_balancer_type = "application"
  idle_timeout       = "90"
  security_groups    = [aws_security_group.public_load_balancer_security_group.id]
  subnets            = ["subnet-9ee89ffa", "subnet-2ff85972"]
  #subnets                    = values(local.subnet_ids)
  enable_deletion_protection = true

  access_logs {
    bucket  = var.load_balancer_access_logs_s3_bucket_name
    prefix  = "${var.environment}-${var.service_name}-public-lb"
    enabled = true
  }

  tags = {
    environment        = var.environment
    service_name       = var.service_name
    application_family = var.application_family
    terraformed        = true
  }
}

resource "aws_lb_listener" "public_load_balancer_https_listener" {
  load_balancer_arn = aws_lb.public_application_load_balancer.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = data.aws_acm_certificate.theorchard_io.arn

  default_action {
    target_group_arn = aws_lb_target_group.public_fargate_target_group.arn
    type             = "forward"
  }

  depends_on = [aws_lb_target_group.public_fargate_target_group]

  tags = {
    environment        = var.environment
    service_name       = var.service_name
    application_family = var.application_family
    terraformed        = true
  }
}

resource "aws_lb_target_group" "public_fargate_target_group" {
  name                 = "${var.environment}-${var.service_name}-public"
  port                 = "8080"
  protocol             = "HTTP"
  target_type          = "ip"
  deregistration_delay = "60"
  vpc_id               = module.vpc_info.vpc_id

  health_check {
    enabled             = true
    healthy_threshold   = "3"
    interval            = "10"
    matcher             = "200"
    path                = "/hello/"
    port                = "8080"
    protocol            = "HTTP"
    timeout             = "5"
    unhealthy_threshold = "3"
  }

  stickiness {
    type            = "lb_cookie"
    cookie_duration = "86400"
    enabled         = false
  }

  tags = {
    environment        = var.environment
    service_name       = var.service_name
    application_family = var.application_family
    terraformed        = true
  }

  depends_on = [aws_lb.public_application_load_balancer]
}

resource "aws_security_group_rule" "allow_inbound_from_public_load_balancer" {
  type                     = "ingress"
  from_port                = "8080"
  to_port                  = "8080"
  protocol                 = "TCP"
  source_security_group_id = aws_security_group.public_load_balancer_security_group.id
  security_group_id        = module.ows_service_environment.fargate_security_group_id
}

resource "aws_wafv2_web_acl_association" "waf_association" {
  resource_arn = aws_lb.public_application_load_balancer.arn
  web_acl_arn  = data.aws_wafv2_web_acl.fargate_service_waf.arn
}

resource "aws_route53_record" "public_load_balancer_route53_record" {
  provider = aws.networking

  zone_id = data.aws_route53_zone.route53_zone.id
  name    = "${var.environment}-${var.service_name}-public"
  type    = "A"

  alias {
    name                   = aws_lb.public_application_load_balancer.dns_name
    zone_id                = aws_lb.public_application_load_balancer.zone_id
    evaluate_target_health = true
  }
}

module "ows_service_environment" {
  source = "../../../../"

  providers = {
    aws.dns = aws.networking
  }

  environment                      = var.environment
  service_name                     = var.service_name
  application_family               = var.application_family
  aws_region                       = var.aws_region
  commit_sha                       = "latest"
  container_port                   = "8080"
  task_type                        = "web_service"
  desired_task_count               = 1
  task_cpu                         = 2048
  task_memory                      = 4096
  maximum_capacity                 = 4
  minimum_capacity                 = 1
  override_route53_zone_id         = data.aws_route53_zone.route53_zone.zone_id
  additional_lb_target_group_arns  = [aws_lb_target_group.public_fargate_target_group.arn]
  web_service_health_check_command = "curl -s -f -o /dev/null http://localhost:8080/hello/ || exit 1"
  fargate_service_subnets = [
    "subnet-44c19a21",
    "subnet-b649dfef",
  ]

  load_balancer_subnets = [
    "subnet-44c19a21",
    "subnet-b649dfef",
  ]
  # These are optional
  additional_tags = {
    "user_supplied_tag_1" = "some_project",
    "user_supplied_tag_2" = "orchard"
  }

  vpc_id = module.vpc_info.vpc_id

  environment_variables = [
    {
      Environment = "${var.environment}"
    },
  ]
}
