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

  default_tags {
    tags = module.default_tags.tags
  }
}

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

  default_tags {
    tags = module.default_tags.tags
  }
}

# Terraform backends cannot contain interpolations
terraform {
  backend "s3" {
    bucket  = "qa-permissions-platform-terraform-state"
    key     = "qa/ows-pdp/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

data "aws_caller_identity" "current" {}

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

  environment = var.environment
}

module "service_info" {
  for_each     = toset(local.downstream_services)
  source       = "git@github.com:theorchard/terraform-service-info.git//?ref=1.0.0"
  service_name = each.value
  environment  = var.environment
}

data "aws_route53_zone" "route53_zone" {
  name = var.domain_name
}

data "aws_route53_zone" "route53_zone_networking" {
  provider = aws.networking
  name     = "theorchard.io."
}

data "aws_secretsmanager_secret" "datadog_api_key" {
  name = "${var.environment}/datadog/DD_API_KEY"
}

data "aws_secretsmanager_secret" "splitio_api_key" {
  name = "${var.environment}/split/API_KEY"
}

data "aws_dynamodb_table" "dynamo_table_identity" {
  name = var.dynamo_table_identity
}

data "aws_elasticache_replication_group" "pp_elasticache" {
  replication_group_id = "${var.environment}-pp-elasticache"
}

data "aws_iam_policy_document" "dynamodb_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "dynamodb:BatchWriteItem",
      "dynamodb:DeleteItem",
      "dynamodb:Query",
      "dynamodb:UpdateItem"
    ]
    resources = [
      data.aws_dynamodb_table.dynamo_table_identity.arn
    ]
  }
}

resource "aws_iam_policy" "dynamodb_policy" {
  name   = "dynamo_${var.environment}_${var.service_name}_pp_identity_RW"
  policy = data.aws_iam_policy_document.dynamodb_policy_document.json
}


# Environment variables
# This must be a list of maps with at least one element.
locals {
  environment_variables = [
    {
      Environment = var.environment
    },
    {
      DD_PROFILING_ENABLED = var.dd_profiling_enabled
    },
    {
      DD_TRACE_WRAP_SPAN_NAME_INCLUDE_CLASS = "true"
    },
    {
      # Diagnostic safety net for PP-1487 ddtrace upgrade: dump a native
      # C/Python traceback to stderr if the process segfaults (exit 139).
      PYTHONFAULTHANDLER = "1"
    },
    {
      JWT_AUTH_ENABLED = var.jwt_auth_enabled
    },
    {
      THEORCHARD_API_AUDIENCE = var.the_orchard_api_audience
    },
    {
      M2M_API_AUDIENCE = var.m2m_api_audience
    },
    {
      DYNAMODB_TABLE_IDENTITY = var.dynamo_table_identity
    },
    {
      DYNAMODB_TCP_KEEP_ALIVE = var.dynamodb_tcp_keep_alive
    },
    {
      CERBOS_SERVER_HOST = "https://${var.environment}-cerbos.${var.environment}-permissions-platform.theorchard.io/"
    },
    {
      CERBOS_BATCH_SIZE = var.cerbos_batch_size
    },
    {
      CERBOS_REQUEST_RETRIES = var.cerbos_request_retries
    },
    {
      SPLITIO_IMPRESSIONS_MODE = var.splitio_impressions_mode
    },
    {
      SPLITIO_PREFORKED_INIT = var.splitio_preforked_init
    },
    {
      REDIS_URL = "rediss://${data.aws_elasticache_replication_group.pp_elasticache.primary_endpoint_address}:6379"
    },
    {
      CACHE_USE_REDIS = var.cache_use_redis
    },
    {
      DD_REDIS_SERVICE = "${var.service_name}-redis"
    },
    {
      REDIS_CACHE_TTL_SECONDS = var.redis_cache_ttl_seconds
    },
    {
      SENTRY_DSN = module.sentry_ows_pdp.sentry_key_dsn_public_output
    },
    {
      CACHE_TTL_SECONDS_IDENTITY_ALLOWED_TENANTS = var.cache_ttl_seconds_identity_allowed_tenants
    },
    {
      CACHE_TTL_SECONDS_IDENTITY_TENANT_ROLES = var.cache_ttl_seconds_identity_tenant_roles
    },
  ]
}

module "ows_service_fargate_environment" {
  source = "git@github.com:theorchard/terraform-fargate.git//?ref=6.4.1"

  providers = {
    aws.dns = aws.networking
  }

  environment                              = var.environment
  service_name                             = var.service_name
  aws_region                               = var.aws_region
  container_port                           = "8080"
  custom_waf_arn                           = module.pdp_waf.waf_blocking_arn_output
  task_type                                = "web_service"
  desired_task_count                       = 4
  minimum_capacity                         = 4
  maximum_capacity                         = 8
  task_cpu                                 = 2048
  task_memory                              = 4096
  load_balancer_access_logs_s3_bucket_name = "orch-elb-logs"
  vpc_id                                   = module.vpc_info.vpc_id
  fargate_service_subnets                  = module.vpc_info.default_private_subnet_ids
  load_balancer_subnets                    = module.vpc_info.default_private_subnet_ids
  application_family                       = var.application_family

  # Parity with old version of task definition
  fluentbit_task_memory = var.fluentbit_task_memory

  iam_managed_policy_attachments = [
    aws_iam_policy.dynamodb_policy.arn
  ]

  https_listener_allow_prefix_list_names = [
    "prod-orcd-private-subnet-prefix-list",
    "shared-orcd-private-subnet-prefix-list",
    "qa-fansifter-private-subnet-prefix-list",
    "qa-orcd-private-subnet-prefix-list",
    "uat-orcd-private-subnet-prefix-list",
    "uat-accounting-private-subnet-prefix-list",
    "qa-accounting-private-subnet-prefix-list",
  ]

  https_listener_allow_security_group_ids = flatten(
    [for service in module.service_info : service.security_groups]
  )

  environment_variables = local.environment_variables
  auth_issuers          = var.auth_issuers
  secrets = [
    {
      SPLITIO_API_KEY = data.aws_secretsmanager_secret.splitio_api_key.name
    }
  ]
}

module "ows_pdp_fargate_service_dashboard" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/service?ref=6.16.1"

  environment                 = var.environment
  environment_type            = "fargate"
  service_name                = var.service_name
  service_4xx_monitor_enabled = false
  application_family          = var.application_family
  teams                       = [var.application_family]

  notification_endpoints            = "@slack-permissions-platform-alerts"
  escalation_notification_endpoints = "@slack-permissions-platform-alerts"
}

module "sentry_ows_pdp" {
  source = "git@github.com:theorchard/terraform-sentry.git?ref=5.0.0"

  environment        = var.environment
  platform           = "python"
  service_name       = var.service_name
  application_family = var.application_family
}

module "pdp_waf" {
  source       = "git@github.com:theorchard/terraform-aws-waf.git//?ref=2.0.2"
  environment  = var.environment
  service_name = var.service_name
  aws_region   = var.aws_region

  count_waf_enabled                 = false
  block_waf_enabled                 = true
  gsirt_ip_block_rule_group_enabled = false

  excluded_rules = [
    "SizeRestrictions_BODY",
  ]
}
