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  = "orcd-terraform-state"
    key     = "qa/vector/encoder/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

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

  environment = var.environment
}

data "aws_caller_identity" "current" {}

data "aws_rds_cluster" "art_relations" {
  cluster_identifier = "${var.environment}-art-relations"
}

data "aws_rds_cluster" "direct_delivery" {
  cluster_identifier = "${var.environment}-direct-delivery-cluster"
}

data "aws_elasticache_replication_group" "vector_cache" {
  replication_group_id = "${var.environment}-vector"
}

data "aws_iam_policy" "s3_mezzanine_dir_readonly_policy" {
  name = "S3-${var.s3_video_bucket}-mezzanine-RO"
}

data "aws_iam_policy" "s3_mezzanine_assets_dir_readonly_policy" {
  name = "S3-${var.s3_mezz_bucket}-RO"
}

# RW access to encoding buckets
data "aws_iam_policy" "encoding_s3_policy" {
  for_each = {
    for policy in local.s3_policies_to_attach : policy.policy_name => policy
  }
  name = each.value.policy_name
}

data "aws_iam_policy_document" "kms_decryption_policy" {
  statement {
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
    ]

    resources = [
      aws_kms_key.kms_key.arn,
    ]
  }
}

# common sentry in qa for all encoders
module "encoding_worker_sentry_project" {
  source             = "git@github.com:theorchard/terraform-sentry.git//?ref=5.0.0"
  service_name       = var.service_name
  environment        = var.environment
  teams              = [var.environment]
  application_family = var.application_family
  platform           = "php"
}

# Create KMS key and policies for certain encrypted configuration
resource "aws_kms_key" "kms_key" {
  description             = "${var.environment}-${var.service_name}"
  enable_key_rotation     = true
  deletion_window_in_days = 30
  tags                    = local.tags
}

resource "aws_kms_alias" "kms_alias" {
  name          = "alias/${var.environment}-${var.service_name}"
  target_key_id = aws_kms_key.kms_key.key_id
}

# Create KMS policy
resource "aws_iam_policy" "kms_policy" {
  name   = "KMS-${var.environment}-${var.service_name}-policy"
  policy = data.aws_iam_policy_document.kms_decryption_policy.json
  tags   = local.tags
}

# Video Encoding Worker
module "qa_vector_encoder_video_ecs_service" {
  for_each = {
    for service in local.flattened_video_service_list : "physical_location_${service.physical_location}-encoding_priority_${service.encoding_priority}" => service
  }

  source = "git@github.com:theorchard/terraform-fargate.git//?ref=5.5.1"

  providers = {
    aws.dns = aws.networking
  }

  environment                           = var.environment
  service_name                          = "${var.service_name}-video-phys-loc-${each.value.physical_location}-p${each.value.encoding_priority}"
  non_ecr_image                         = "086679231553.dkr.ecr.${var.aws_region}.amazonaws.com/${var.service_name}:latest"
  vpc_id                                = module.vpc_info.vpc_id
  application_family                    = var.application_family
  secrets_manager_service_name          = var.service_name
  aws_region                            = var.aws_region
  commit_sha                            = "latest"
  task_type                             = "worker"
  health_check_command                  = "pgrep php"
  desired_task_count                    = each.value.min_task_count # Set during service creation here and controlled henceforth by autoscaling
  task_cpu                              = 256
  task_memory                           = 1024
  minimum_capacity                      = each.value.min_task_count
  maximum_capacity                      = each.value.max_task_count
  task_protection_policy_enabled        = true
  splitio_enabled                       = true
  ows_machine_to_machine_enabled        = false
  autoscaling_cpu_policy_enabled        = false
  autoscaling_memory_policy_enabled     = false
  external_autoscaling_policy_enabled   = true
  stopped_task_monitoring_enabled       = true
  fargate_spot_capacity_provider_weight = 100
  task_placement_failure_alert_enabled  = true

  # IAM policies used by the task role to pull configs from s3
  iam_managed_policy_attachments = [
    aws_iam_policy.kms_policy.arn,
    aws_iam_policy.vector_encoder_m2m_token_secrets_manager_policy.arn,
  ]

  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      PHP_ENTRYPOINT = "encode_tracks.php"
    },
    {
      USER_AGENT = "${var.environment}-${var.service_name}-video"
    },
    {
      ALLOWED_ENCODER_IDS = var.video_encoder_id
    },
    {
      API_GATEWAY = "ul7vwqbzwa-vpce-04f8c4be29fb2bd59.execute-api.us-east-1.amazonaws.com"
    },
    {
      ENCODING_PRIORITIES = each.value.encoding_priority
    },
    {
      LOG_LEVEL = "7"
    },
    {
      PHYSICAL_LOCATION_ID = each.value.physical_location
    },
    {
      SCRIPT_COUNT = "5"
    },
    {
      CURL_FORBID_REUSE = "true"
    },
    {
      USE_DOGSTATSD = "true"
    },
    {
      SENTRY_DSN = module.encoding_worker_sentry_project.sentry_key_dsn_public_output
    },
    {
      SERVICE_NAME = var.service_name
    },
    {
      DD_DB_HOST = data.aws_rds_cluster.direct_delivery.endpoint
    },
    {
      DD_DB_RW_USERNAME = "qa-dd_user_rw"
    },
    {
      DD_DB_RO_USERNAME = "qa-dd_user_ro"
    },
    {
      DD_DB_EO_USERNAME = "qa-dd_user"
    },
    {
      AR_DB_HOST = data.aws_rds_cluster.art_relations.reader_endpoint
    },
    {
      AR_DB_USERNAME = "qa-theorchard_dd"
    },
    {
      S3_XML_BACKUP_BUCKET = "qa-vector-audit"
    },
    {
      S3_XML_BACKUP_PATH = "/metadata"
    },
    {
      CACHE_HOST = data.aws_elasticache_replication_group.vector_cache.primary_endpoint_address
    },
    {
      ENCODING_QUEUE_NAME_PATTERN = "qa-encoding{encoder-id}_e{priority(7)}_d{dms-priority(7)}"
    },
    {
      DELIVERY_QUEUE_NAME_PATTERN = "qa-delivery{encoder-id}_e{priority(7)}_d{dms-priority(7)}"
    },
    {
      APP_LOG_LEVEL = var.app_log_level
    }
  ]

  secrets = [
    {
      AR_DB_PASSWORD = "${var.environment}/${var.service_name}/AR_DB_PASSWORD"
    },
    {
      DD_DB_RO_PASSWORD = "${var.environment}/${var.service_name}/DD_DB_RO_PASSWORD"
    },
    {
      DD_DB_RW_PASSWORD = "${var.environment}/${var.service_name}/DD_DB_RW_PASSWORD"
    },
    {
      DD_DB_EO_PASSWORD = "${var.environment}/${var.service_name}/DD_DB_EO_PASSWORD"
    },
    {
      AWS_KEY_ID = "${var.environment}/${var.service_name}/AWS_KEY_ID"
    },
    {
      AWS_SECRET_KEY = "${var.environment}/${var.service_name}/AWS_SECRET_KEY"
    },
  ]
}

# Every service in a given physical location should have the S3 policy for that location attached to it
resource "aws_iam_role_policy_attachment" "vector_encoder_video_secrets_manager_storage_credential_policy_attachment" {
  for_each = {
    for service in local.flattened_video_service_list : "physical_location_${service.physical_location}-encoding_priority_${service.encoding_priority}" => service
  }
  role       = module.qa_vector_encoder_video_ecs_service[each.key].fargate_task_iam_execution_role_name
  policy_arn = aws_iam_policy.secrets_manager_storage_credential_policy[each.value.physical_location].arn
}

# Create policy to List, Read and delete message from Encoding SQS queue
data "aws_iam_policy_document" "sqs_encoding_queue_policy_document" {
  statement {
    actions = [
      "sqs:GetQueueAttributes",
      "sqs:GetQueueUrl",
      "sqs:ListQueues",
      "sqs:SendMessageBatch",
      "sqs:SendMessage",
      "sqs:CreateQueue",
      "sqs:DeleteMessage",
      "sqs:ReceiveMessage",
    ]

    resources = [
      # To match arn:aws:sqs:us-east-1:437795906767:qa-encoding18_e0000005_d0000471
      "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${var.environment}-encoding17_e*",
      "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${var.environment}-encoding17_e*/*",
      "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${var.environment}-encoding18_e*",
      "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:${var.environment}-encoding18_e*/*",
    ]
  }

  statement {
    actions = [
      "sqs:GetQueueAttributes",
      "sqs:ListQueues"
    ]

    resources = [
      "arn:aws:sqs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*",
    ]
  }
}

resource "aws_iam_policy" "sqs_encoding_queue_policy" {
  name   = "sqs-${var.environment}-encoding-queue-R-policy"
  policy = data.aws_iam_policy_document.sqs_encoding_queue_policy_document.json
}

# ows-request dynamo db policy
module "vector_encoder_service_owsrequest" {
  source = "git@github.com:theorchard/terraform-owsrequest.git//?ref=1.0.1"

  environment_name   = var.environment
  service_name       = var.service_name
  policy_description = "A policy to access dynamo owsrequest table"
}

# Audio Encoding Worker
module "qa_vector_encoder_audio_ecs_service" {
  for_each = {
    for service in local.flattened_audio_service_list : "physical_location_${service.physical_location}-encoding_priority_${service.encoding_priority}" => service
  }

  source = "git@github.com:theorchard/terraform-fargate.git//?ref=6.1.1"

  providers = {
    aws.dns = aws.networking
  }

  environment                           = var.environment
  service_name                          = "${var.service_name}-audio-phys-loc-${each.value.physical_location}-p${each.value.encoding_priority}"
  non_ecr_image                         = "086679231553.dkr.ecr.${var.aws_region}.amazonaws.com/vector-worker:latest"
  vpc_id                                = module.vpc_info.vpc_id
  application_family                    = var.application_family
  secrets_manager_service_name          = var.service_name
  aws_region                            = var.aws_region
  commit_sha                            = "latest"
  task_type                             = "worker"
  health_check_command                  = "pgrep php"
  desired_task_count                    = each.value.min_task_count # Set during service creation here and controlled henceforth by autoscaling
  task_cpu                              = 256
  task_memory                           = 1024
  minimum_capacity                      = each.value.min_task_count
  maximum_capacity                      = each.value.max_task_count
  task_protection_policy_enabled        = true
  splitio_enabled                       = true
  ows_machine_to_machine_enabled        = false
  autoscaling_cpu_policy_enabled        = false
  autoscaling_memory_policy_enabled     = false
  external_autoscaling_policy_enabled   = true
  stopped_task_monitoring_enabled       = true
  fargate_capacity_provider_base        = 1
  fargate_capacity_provider_weight      = 1
  fargate_spot_capacity_provider_weight = 4
  force_new_deployment                  = true
  task_placement_failure_alert_enabled  = true

  # IAM policies used by the task role to pull configs from s3
  iam_managed_policy_attachments = [
    aws_iam_policy.kms_policy.arn,
    aws_iam_policy.vector_encoder_m2m_token_secrets_manager_policy.arn,
  ]

  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      PHP_ENTRYPOINT = "encode_tracks.php"
    },
    {
      USER_AGENT = "${var.environment}-${var.service_name}-audio"
    },
    {
      ALLOWED_ENCODER_IDS = var.audio_encoder_id
    },
    {
      API_GATEWAY = "ul7vwqbzwa-vpce-04f8c4be29fb2bd59.execute-api.us-east-1.amazonaws.com"
    },
    {
      ENCODING_PRIORITIES = each.value.encoding_priority
    },
    {
      LOG_LEVEL = "7"
    },
    {
      PHYSICAL_LOCATION_ID = each.value.physical_location
    },
    {
      SCRIPT_COUNT = "10"
    },
    {
      CURL_FORBID_REUSE = "true"
    },
    {
      USE_DOGSTATSD = "true"
    },
    {
      SENTRY_DSN = module.encoding_worker_sentry_project.sentry_key_dsn_public_output
    },
    {
      SERVICE_NAME = var.service_name
    },
    {
      DD_DB_HOST = data.aws_rds_cluster.direct_delivery.endpoint
    },
    {
      DD_DB_RW_USERNAME = "qa-dd_user_rw"
    },
    {
      DD_DB_RO_USERNAME = "qa-dd_user_ro"
    },
    {
      DD_DB_EO_USERNAME = "qa-dd_user"
    },
    {
      AR_DB_HOST = data.aws_rds_cluster.art_relations.reader_endpoint
    },
    {
      AR_DB_USERNAME = "qa-theorchard_dd"
    },
    {
      S3_XML_BACKUP_BUCKET = "qa-vector-audit"
    },
    {
      S3_XML_BACKUP_PATH = "/metadata"
    },
    {
      CACHE_HOST = data.aws_elasticache_replication_group.vector_cache.primary_endpoint_address
    },
    {
      ENCODING_QUEUE_NAME_PATTERN = "qa-encoding{encoder-id}_e{priority(7)}_d{dms-priority(7)}"
    },
    {
      DELIVERY_QUEUE_NAME_PATTERN = "qa-delivery{encoder-id}_e{priority(7)}_d{dms-priority(7)}"
    },
    {
      APP_LOG_LEVEL = var.app_log_level
    }
  ]

  secrets = [
    {
      AR_DB_PASSWORD = "${var.environment}/${var.service_name}/AR_DB_PASSWORD"
    },
    {
      DD_DB_RO_PASSWORD = "${var.environment}/${var.service_name}/DD_DB_RO_PASSWORD"
    },
    {
      DD_DB_RW_PASSWORD = "${var.environment}/${var.service_name}/DD_DB_RW_PASSWORD"
    },
    {
      DD_DB_EO_PASSWORD = "${var.environment}/${var.service_name}/DD_DB_EO_PASSWORD"
    },
    {
      AWS_KEY_ID = "${var.environment}/${var.service_name}/AWS_KEY_ID"
    },
    {
      AWS_SECRET_KEY = "${var.environment}/${var.service_name}/AWS_SECRET_KEY"
    },
  ]
}

resource "aws_iam_role_policy_attachment" "vector_encoder_audio_secrets_manager_storage_credential_policy_attachment" {
  for_each = {
    for service in local.flattened_audio_service_list : "physical_location_${service.physical_location}-encoding_priority_${service.encoding_priority}" => service
  }
  role       = module.qa_vector_encoder_audio_ecs_service[each.key].fargate_task_iam_execution_role_name
  policy_arn = aws_iam_policy.secrets_manager_storage_credential_policy[each.value.physical_location].arn
}
