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          = "accounts-platform"
}

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 {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/ows-users/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

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

  environment = var.environment
}

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

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

data "aws_route53_zone" "route53_zone_networking" {
  provider = aws.networking

  name = "theorchard.io"
}

data "aws_caller_identity" "current" {}

data "aws_wafv2_web_acl" "public_shared_waf" {
  name  = "${var.environment}-public-shared-regional-waf-block"
  scope = "REGIONAL"
}

data "aws_sqs_queue" "notifications_queue" {
  name = "${var.environment}-notifications"
}

# SNS policy document.
data "aws_iam_policy_document" "ows_users_mobile_notifications_sns_policy" {
  statement {
    effect = "Allow"
    actions = [
      "sns:ListTopics",
      "sns:CreatePlatformEndpoint",
      "sns:DeleteEndpoint",
      "sns:SetTopicAttributes",
      "sns:ListEndpointsByPlatformApplication",
      "sns:SetEndpointAttributes",
      "sns:Publish",
      "sns:SetPlatformApplicationAttributes",
      "sns:Subscribe",
      "sns:Unsubscribe",
      "sns:ConfirmSubscription",
      "sns:ListTagsForResource",
      "sns:ListSubscriptionsByTopic",
      "sns:GetTopicAttributes",
      "sns:CreatePlatformApplication",
      "sns:SetSMSAttributes",
      "sns:CreateTopic",
      "sns:GetPlatformApplicationAttributes",
      "sns:GetSubscriptionAttributes",
      "sns:ListSubscriptions",
      "sns:ListPhoneNumbersOptedOut",
      "sns:GetEndpointAttributes",
      "sns:SetSubscriptionAttributes",
      "sns:ListPlatformApplications",
      "sns:GetSMSAttributes"
    ]
    resources = [
      "arn:aws:sns:us-east-1:437795906767:app/APNS/PROD_Orchard_Go",
      "arn:aws:sns:us-east-1:437795906767:app/APNS/prod-awal",
      "arn:aws:sns:us-east-1:437795906767:app/APNS/prod-sme",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/PROD_Orchard_Go_FCM",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/prod-awal",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/prod-sme",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/reactexpoapp"
    ]
  }
}

data "aws_iam_policy_document" "sns_platform_application_delivery_status_log_role_assume_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type = "Service"

      identifiers = [
        "sns.amazonaws.com",
      ]
    }
  }
}

data "aws_iam_policy_document" "sns_platform_application_delivery_status_log_role_policy" {
  # checkov:skip=CKV_AWS_111:need to revert production outage
  statement {

    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
      "logs:PutMetricFilter",
      "logs:PutRetentionPolicy",
    ]

    resources = [
      "*"
    ]
  }
}

# DynamoDB policy document for social auth table
data "aws_iam_policy_document" "dynamodb_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:Query",
      "dynamodb:UpdateItem"
    ]
    resources = [
      "arn:aws:dynamodb:us-east-1:437795906767:table/prod_social-auth",
      "arn:aws:dynamodb:us-east-1:437795906767:table/prod_social-auth/*"
    ]
  }
}

data "aws_iam_policy" "pre_existing_policies" {
  for_each = toset([
    "Dynamo-prod-ows-users-RW",
    "Dynamo-prod-ows-users-owsrequest",
    "SQS-prod-notifications-RW",
    "bff-feature-fm-GetSecret",
    "Dynamo-prod-ows-auth-fullaccess",
  ])
  name = each.value
}

resource "aws_iam_role" "sns_platform_application_delivery_status_log_role" {
  name               = "${var.environment}-sns-platform-application-delivery-status-log-role"
  assume_role_policy = data.aws_iam_policy_document.sns_platform_application_delivery_status_log_role_assume_role_policy.json
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

resource "aws_iam_policy" "sns_platform_application_delivery_status_log_policy" {
  name   = "${var.environment}-sns-platform-application-delivery-status-log-policy"
  policy = data.aws_iam_policy_document.sns_platform_application_delivery_status_log_role_policy.json
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

resource "aws_iam_role_policy_attachment" "sns_platform_application_delivery_status_log_policy_attachment" {
  role       = aws_iam_role.sns_platform_application_delivery_status_log_role.id
  policy_arn = aws_iam_policy.sns_platform_application_delivery_status_log_policy.arn
}

resource "aws_cloudwatch_log_subscription_filter" "datadog_lambda_function_log_filter" {
  count           = length(var.sns_delivery_cloudwatch_log_groups)
  name            = "${var.environment}-sns-platform-app-delivery-logs-filter-${count.index}"
  log_group_name  = var.sns_delivery_cloudwatch_log_groups[count.index]
  filter_pattern  = ""
  destination_arn = "arn:aws:lambda:us-east-1:${data.aws_caller_identity.current.account_id}:function:DatadogLambdaFunction"
  distribution    = "ByLogStream"
}

module "ows_users_cache" {
  source = "git@github.com:theorchard/terraform-elasticache.git//?ref=3.1.1"

  providers = {
    aws.dns = aws.networking
  }

  environment                    = var.environment
  service_name                   = var.service_name
  application_family             = var.application_family
  cache_engine                   = "redis"
  cache_node_type                = "cache.t4g.micro"
  cache_subnet_group_name        = "${var.environment}-elasticache-subnet-group"
  cache_parameter_group_name     = "default.redis5.0"
  redis_engine_version           = "5.0.6"
  vpc_id                         = module.vpc_info.vpc_id
  route53_zone_id                = data.aws_route53_zone.route53_zone.zone_id
  additional_cidr_blocks_enabled = "true"
  additional_cidr_blocks = [
    "10.10.40.0/22",
    "10.10.141.0/29"
  ]
}

module "datadog_elasticache" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/elasticache?ref=6.13.6"

  environment        = var.environment
  service_name       = var.service_name
  application_family = var.application_family
  teams              = var.teams

  notification_endpoints            = var.application_alert_channel
  escalation_notification_endpoints = var.application_alert_channel
}


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

  providers = {
    aws.dns = aws.networking
  }

  environment        = var.environment
  service_name       = var.service_name
  aws_region         = var.aws_region
  application_family = var.application_family
  commit_sha         = "latest"
  container_port     = var.container_port
  task_type          = "web_service"
  desired_task_count = 10
  task_cpu           = 2048
  task_memory        = 4096
  maximum_capacity   = 20
  minimum_capacity   = 3

  vpc_id                          = module.vpc_info.vpc_id
  https_listener_certificate_id   = split("/", data.aws_acm_certificate.theorchard_io.arn)[1]
  iam_policy_file_enabled         = true
  additional_lb_target_group_arns = [aws_lb_target_group.proxy_fargate_target_group.arn]

  autoscaling_cpu_policy_enabled                      = false
  autoscaling_active_connections_policy_enabled       = true
  scaling_active_connection_count_scale_out_threshold = 20
  scaling_active_connection_count_scale_in_threshold  = 10

  iam_managed_policy_attachments = concat(
    [
      for policy in data.aws_iam_policy.pre_existing_policies : policy.arn
    ],
    [
      aws_iam_policy.ows_users_sns_policy.arn,
      aws_iam_policy.ows_users_dynamodb_social_auth_table_access_policy.arn
    ]
  )

  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  load_balancer_subnets = module.vpc_info.default_private_subnet_ids

  https_listener_allow_prefix_list_names = [
    "shared-orcd-jump-box-private-subnet-prefix-list",
    "${var.environment}-fansifter-private-subnet-prefix-list",
  ]

  secrets = [
    {
      SENTRY_DSN = "${var.environment}/${var.service_name}/SENTRY_DSN"
    },
    {
      AR_MYSQL_HOST = "${var.environment}/${var.service_name}/AR_MYSQL_HOST"
    },
    {
      AR_MYSQL_USER = "${var.environment}/${var.service_name}/AR_MYSQL_USER"
    },
    {
      AR_MYSQL_PASSWORD = "${var.environment}/${var.service_name}/AR_MYSQL_PASSWORD"
    },
    {
      AUTH0_MACHINE_CLIENT_ID = "${var.environment}/${var.service_name}/AUTH0_MACHINE_CLIENT_ID"
    },
    {
      AUTH0_MACHINE_CLIENT_SECRET = "${var.environment}/${var.service_name}/AUTH0_MACHINE_CLIENT_SECRET"
    },
    {
      FEATURE_FM_SECRET_TOKEN = "${var.environment}/${var.service_name}/FEATURE_FM_SECRET_TOKEN"
    },
    {
      FEATURE_FM_SECRET_TOKEN_KEY = "${var.environment}/${var.service_name}/FEATURE_FM_SECRET_TOKEN_KEY"
    },
    {
      PUBKEY_OA = "${var.environment}/${var.service_name}/PUBKEY_OA"
    },
    {
      PUBKEY_WORKSTATION = "${var.environment}/${var.service_name}/PUBKEY_WORKSTATION"
    },
    {
      SECRET_OA = "${var.environment}/${var.service_name}/SECRET_OA"
    },
    {
      SECRET_WORKSTATION = "${var.environment}/${var.service_name}/SECRET_WORKSTATION"
    },
    {
      ZENDESK_SECRET_KEY = "${var.environment}/${var.service_name}/ZENDESK_SECRET_KEY"
    },
    {
      ZENDESK_MESSAGING_SECRET_KEY = "${var.environment}/${var.service_name}/ZENDESK_MESSAGING_SECRET_KEY"
    },
    {
      ZENDESK_KID = "${var.environment}/${var.service_name}/ZENDESK_KID"
    },
  ]

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      DD_LOGS_INJECTION = "true"
    },
    {
      AR_MYSQL_DATABASE = "art_relations"
    },
    {
      AR_MYSQL_PORT = "3306"
    },
    {
      AWS_REGION = var.aws_region
    },
    {
      FCM_APPLICATION_ARN = var.fcm_application_arn
    },
    {
      APN_APPLICATION_ARN = var.apn_application_arn
    },
    {
      AWAL_FCM_APPLICATION_ARN = var.awal_fcm_application_arn
    },
    {
      AWAL_APN_APPLICATION_ARN = var.awal_apn_application_arn
    },
    {
      SME_FCM_APPLICATION_ARN = var.sme_fcm_application_arn
    },
    {
      SME_APN_APPLICATION_ARN = var.sme_apn_application_arn
    },
    {
      SNS_ARN_PREFIX = "arn:aws:sns:${var.aws_region}:${data.aws_caller_identity.current.account_id}"
    },
    {
      DELIVERY_STATUS_LOGGING_ROLE = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.environment}-sns-platform-application-delivery-status-log-role"
    },
    {
      AUTH0_DOMAIN = "workstation.auth0.com"
    },
    {
      AUTH0_CONNECTION = "art-relations"
    },
    {
      DAEMON_NOTIFICATIONS_SQS_URL = data.aws_sqs_queue.notifications_queue.url
    },
    {
      REDIS_URL = "prod-ows-users-redis.theorchard.io"
    },
    {
      REDIS_CACHE_TTL = var.REDIS_CACHE_TTL
    },
    {
      REDIS_USE_SSL = var.REDIS_USE_SSL
    },
    {
      URL_OA = "https://oa.theorchard.com"
    },
    {
      URL_WORKSTATION = "https://workstation.theorchard.com"
    },
    {
      DYNAMODB_SOCIAL_AUTH_TABLE = "${var.environment}_social-auth"
    },
    {
      NEO4J_URL = var.neo4j_url
    },
    {
      NEO4J_AURA_URL = var.neo4j_aura_url
    },
  ]
}

module "secrets" {
  source   = "git@github.com:theorchard/terraform-secrets-manager.git//?ref=1.5.1"
  for_each = toset(var.secrets_manager_secret_names)

  environment                    = var.environment
  service_name                   = var.service_name
  secret_name                    = each.value
  application_family             = var.application_family
  secret_recovery_window_in_days = 7
}

resource "aws_iam_policy" "ows_users_sns_policy" {
  name   = "SNS-${var.environment}-${var.service_name}-mobile-notifications_sns"
  policy = data.aws_iam_policy_document.ows_users_mobile_notifications_sns_policy.json
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

resource "aws_iam_policy" "ows_users_dynamodb_social_auth_table_access_policy" {
  name   = "DYNAMODB-${var.environment}-${var.service_name}-social-auth-table-access-policy"
  policy = data.aws_iam_policy_document.dynamodb_policy_document.json
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

module "fargate_service_dashboard" {
  source                            = "git@github.com:theorchard/terraform-datadog.git//modules/service?ref=6.13.6"
  environment                       = var.environment
  environment_type                  = "fargate"
  service_name                      = var.service_name
  application_family                = var.application_family
  critical_number_5xx               = var.critical_number_5xx
  critical_recovery_number_5xx      = var.critical_recovery_number_5xx
  warning_number_5xx                = var.warning_number_5xx
  warning_recovery_number_5xx       = var.warning_recovery_number_5xx
  notification_endpoints            = var.application_alert_channel
  escalation_notification_endpoints = var.application_alert_channel
  additional_tags                   = { service_type = "critical" }
  teams                             = [var.application_family]
  service_cpu_time_window           = "last_10m"
  notification_overrides_5xx = {
    endpoints            = "${var.application_alert_channel} ${var.pagerduty_alert_channel} ${var.datadog_oncall_channel}"
    escalation_endpoints = "${var.application_alert_channel} ${var.pagerduty_alert_channel} ${var.datadog_oncall_channel}"
  }
  dependent_applications = var.dependent_applications
}

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

  environment        = var.environment
  service_name       = var.service_name
  application_family = var.application_family
}
