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.region

  default_tags {
    tags = module.default_tags.tags
  }
}

terraform {
  backend "s3" {
    bucket  = "prod-songwhip-terraform-state"
    key     = "prod/songwhip-api/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 "cloudflare_ip_ranges" "cloudflare" {}

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

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

module "secrets_manager_policy" {
  source = "git@github.com:theorchard/terraform-iam-policy-templates.git//documents/secretsmanager/secrets_list?ref=0.4.0"

  secrets = [
    "${var.environment}/${var.service_name}/SONGWHIP_WEBHOOK_KEY",
  ]
  action_types = ["read"]
}

resource "aws_iam_policy" "secrets_manager_access_policy_for_scheduler_job" {
  name        = "SecretsManager-${var.environment}-${var.service_name}-scheduler-policy"
  description = "Access to Secrets Manager for Scheduler Job"
  policy      = module.secrets_manager_policy.policy.json
}

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

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::437795906767:role/prod-jenkins-aws-pipeline-agent",
        "arn:aws:iam::437795906767:role/prod-jenkins-aws-task-agent",
      ]
    }
  }
}

resource "aws_iam_role" "scheduler_role" {
  name               = "${var.environment}-${var.service_name}-scheduler-role"
  assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}

resource "aws_iam_role_policy_attachment" "secrets_manager_policy_attachment" {
  role       = aws_iam_role.scheduler_role.id
  policy_arn = aws_iam_policy.secrets_manager_access_policy_for_scheduler_job.arn
}

// KMS Keys
resource "aws_kms_key" "fan_data_kms_key" {
  description = "KMS key to encrypt/decrypt fan data from songwhip-api on production"

  enable_key_rotation     = true
  deletion_window_in_days = 30

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

resource "aws_kms_alias" "fan_data_kms_alias" {
  name          = "alias/${var.service_name}-fan-data-${var.environment_alias}"
  target_key_id = aws_kms_key.fan_data_kms_key.key_id
}

resource "aws_kms_key" "orchard_token_kms_key" {
  description = "KMS key to encrypt/decrypt a user's orchard token from songwhip-api on production"

  enable_key_rotation     = true
  deletion_window_in_days = 30

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

resource "aws_kms_alias" "orchard_token_kms_alias" {
  name          = "alias/${var.service_name}-orchard-token-${var.environment_alias}"
  target_key_id = aws_kms_key.orchard_token_kms_key.key_id
}

// IAM Policies
data "aws_iam_policy_document" "dynamodb_fan_data_policy_document" {
  statement {
    actions = [
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:Query"
    ]

    resources = [
      "arn:aws:dynamodb:us-east-1:926734670777:table/songwhip-api-fan-data-production"
    ]
  }
}

resource "aws_iam_policy" "dynamodb_fan_data_policy" {
  name   = "DYNAMODB-${var.environment}-${var.service_name}-fan-data"
  policy = data.aws_iam_policy_document.dynamodb_fan_data_policy_document.json
}

data "aws_iam_policy_document" "kms_fan_data_policy_document" {
  statement {
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
      "kms:ReEncrypt*"
    ]

    resources = [
      aws_kms_key.fan_data_kms_key.arn
    ]
  }
}

resource "aws_iam_policy" "kms_fan_data_policy" {
  name   = "KMS-${var.environment}-${var.service_name}-fan-data"
  policy = data.aws_iam_policy_document.kms_fan_data_policy_document.json
}

data "aws_iam_policy_document" "kms_orchard_token_policy_document" {
  statement {
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
      "kms:ReEncrypt*"
    ]

    resources = [
      aws_kms_key.orchard_token_kms_key.arn
    ]
  }
}

resource "aws_iam_policy" "kms_orchard_token_policy" {
  name   = "KMS-${var.environment}-${var.service_name}-orchard-token"
  policy = data.aws_iam_policy_document.kms_orchard_token_policy_document.json
}

data "aws_iam_policy_document" "kms_orchard_dmp_key_policy_document" {
  statement {
    actions = [
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
    ]

    resources = [
      var.orchard_dmp_kms_key_arn
    ]
  }
}

resource "aws_iam_policy" "kms_orchard_dmp_key_policy" {
  name   = "KMS-${var.environment}-${var.service_name}-orchard-dmp-key"
  policy = data.aws_iam_policy_document.kms_orchard_dmp_key_policy_document.json
}

module "s3_content_read_write_delete_policy_document" {
  source = "git@github.com:theorchard/terraform-iam-policy-templates.git//documents/s3/buckets_with_prefixes?ref=0.4.0"

  buckets = [
    {
      bucket = "${var.environment}-songwhip-content"
    }
  ]
  action_types = ["read", "write", "delete"]
}

resource "aws_iam_policy" "s3_content_policy" {
  name   = "S3-${var.environment}-${var.service_name}-content-RW"
  policy = module.s3_content_read_write_delete_policy_document.policy.json
}

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

  providers = {
    aws.dns = aws
  }

  // To be removed once the service is migrated to use Jenkinsfile
  non_ecr_image = "926734670777.dkr.ecr.us-east-1.amazonaws.com/songwhip-api:latest"

  environment                              = var.environment
  service_name                             = var.service_name
  application_family                       = var.application_family
  aws_region                               = var.region
  commit_sha                               = "latest"
  container_port                           = "8080"
  task_type                                = "web_service"
  desired_task_count                       = 4
  task_cpu                                 = 2048
  task_memory                              = 4096
  datadog_task_memory                      = 256
  maximum_capacity                         = 8
  minimum_capacity                         = 4
  health_check_path                        = "/health"
  override_route53_zone_id                 = "Z0134392105296KJ8C5A8"
  load_balancer_access_logs_s3_bucket_name = "prod-songwhip-lb-logs"
  vpc_id                                   = "vpc-00cc75b12f441dc13"
  https_listener_certificate_id            = "5d2fce1b-1a6d-42e6-a58e-f20720053e38"
  load_balancer_is_internal                = "false"
  blocking_waf_enabled                     = false

  prod_https_listener_allow_cidr_blocks = data.cloudflare_ip_ranges.cloudflare.ipv4_cidr_blocks

  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  load_balancer_subnets = module.vpc_info.default_public_subnet_ids

  iam_managed_policy_attachments = [
    aws_iam_policy.dynamodb_fan_data_policy.arn,
    aws_iam_policy.kms_fan_data_policy.arn,
    aws_iam_policy.kms_orchard_token_policy.arn,
    aws_iam_policy.kms_orchard_dmp_key_policy.arn,
    aws_iam_policy.s3_content_policy.arn,
    aws_iam_policy.fargate_sqs_send_policy.arn,
    aws_iam_policy.songwhip_api_bedrock.arn,
  ]

  environment_variables = [
    {
      APPRECIATION_ENGINE_ENABLED = "1"
    },
    {
      AUTH0_ISSUER_BASE_URL = "https://login.distroauth.com"
    },
    {
      AUTH0_M2M_BASE_URL = "https://workstation.auth0.com/"
    },
    {
      AUTH0_M2M_AUDIENCE = "https://workstation.theorchard.com/api"
    },
    {
      DD_LOGS_INJECTION = "true"
    },
    {
      ORCHARD_OWS_URL = "https://ows-grass.theorchard.io/"
    },
    {
      ORCHARD_TOKEN_KMS_KEY_ID = "alias/songwhip-api-orchard-token-production"
    },
    {
      ORCHARD_DMP_KMS_KEY_ID = var.orchard_dmp_kms_key_arn
    },
    {
      ORCHARD_KAFKA_BROKERS = join(",", [
        "b-1.prodmanagedkafkafansi.pmp3ff.c25.kafka.us-east-1.amazonaws.com:9094",
        "b-2.prodmanagedkafkafansi.pmp3ff.c25.kafka.us-east-1.amazonaws.com:9094",
        "b-3.prodmanagedkafkafansi.pmp3ff.c25.kafka.us-east-1.amazonaws.com:9094",
      ])
    },
    {
      POSTGRES_DB = "songwhip_api"
    },
    {
      POSTGRES_PORT = "5432"
    },
    {
      POSTGRES_SSL = "true"
    },
    {
      PUBLIC_ENDPOINT = "https://api.songwhip.com/v3/"
    },
    {
      RECORD_CHANGE_WEBHOOK_URLS = "https://songwhip.com/_edge/hooks/on-record-change"
    },
    {
      SONGWHIP_ANALYTICS_URL = "https://analytics.songwhip.com"
    },
    {
      SONGWHIP_APPRECIATION_ENGINE_ENDPOINT = "https://appreciation-engine.songwhip.com/"
    },
    {
      SONGWHIP_ENV = "production"
    },
    {
      SONGWHIP_LOOKUP_URL = "https://lookup.songwhip.com"
    },
    {
      SONGWHIP_QUEUE_URL = "https://queue.songwhip.com"
    },
    {
      SONGWHIP_RELEASE_TASKS_URL = "https://release-tasks.songwhip.com/"
    },
    {
      SONGWHIP_TRUSTED_ORIGINS = "songwhip.com,staging.songwhip.com,localhost"
    },
    {
      SONGWHIP_WEB_URL = "https://songwhip.com"
    },
    {
      # Default service user ID for webhook operations
      SONGWHIP_WEBHOOK_USER_ID = "41860"
    },
    {
      PORT = "8080"
    },
    {
      CLOUDFLARE_ZONE_ID = "e76b7d9dca7f8b72c3310805a236271a"
    },
    {
      CLOUDFLARE_ACCOUNT_ID = "229e27eb2e8337e21e3a1e26b1daba51"
    },
    {
      CLOUDFLARE_ACCOUNT_EMAIL = "songwhip_cf_service@theorchard.com"
    },
    {
      CLOUDFLARE_CUSTOM_DOMAINS_WORKER_NAME = "songwhip-web-production"
    },
    {
      CLOUDFLARE_KV_NAMESPACE_ID = "5a828d9c55384344ba86d79c47803d47"
    },
    {
      AWS_UPLOAD_BUCKET = "prod-songwhip-content"
    },
    {
      SQS_QUEUE_URL = module.songwhip_api_sqs.queue_url
    },
    {
      SENTRY_DSN = module.songwhip_api_sentry_project.sentry_key_dsn_public_output
    },
    {
      CLOUDFRONT_KEY_PAIR_ID = "K1T4CTKLZWDT5A"
    },
    {
      CLOUDFRONT_DOMAIN = "hls.aws-prod.songwhip.com"
    },
    {
      CLOUDFRONT_COOKIE_LIFETIME_HOURS = "3"
    },
    {
      CLOUDFRONT_COOKIE_SECURE = "true"
    },
    {
      CLOUDFRONT_COOKIE_DOMAIN = "songwhip.com"
    },
    {
      REDIS_HOST = module.songwhip_api_redis.redis_primary_endpoint_address
    },
    {
      REDIS_PORT = "6379"
    },
    {
      REDIS_USE_TLS = "true"
    },
    {
      BEDROCK_REGION = var.region
    },
    {
      BEDROCK_MODEL_ID = var.bedrock_model_id
    },
    {
      BEDROCK_GUARDRAIL_ID = aws_bedrock_guardrail.songwhip_api_public_copy.guardrail_id
    },
    {
      BEDROCK_GUARDRAIL_VERSION = aws_bedrock_guardrail_version.songwhip_api_public_copy_v1.version
    },
  ]

  secrets = [
    {
      AUTH0_CLIENT_ID = "${var.environment}/${var.service_name}/AUTH0_CLIENT_ID"
    },
    {
      AUTH0_CLIENT_SECRET = "${var.environment}/${var.service_name}/AUTH0_CLIENT_SECRET"
    },
    {
      AUTH0_M2M_CLIENT_ID = "${var.environment}/${var.service_name}/AUTH0_M2M_CLIENT_ID"
    },
    {
      AUTH0_M2M_CLIENT_SECRET = "${var.environment}/${var.service_name}/AUTH0_M2M_CLIENT_SECRET"
    },
    {
      GOOGLE_AUTH_CLIENT_ID = "${var.environment}/${var.service_name}/GOOGLE_AUTH_CLIENT_ID"
    },
    {
      JWT_SECRET = "${var.environment}/${var.service_name}/JWT_SECRET"
    },
    {
      POSTGRES_HOST = "${var.environment}/${var.service_name}/POSTGRES_HOST"
    },
    {
      POSTGRES_PASSWORD = "${var.environment}/${var.service_name}/POSTGRES_PASSWORD"
    },
    {
      POSTGRES_USER = "${var.environment}/${var.service_name}/POSTGRES_USER"
    },
    {
      SENDINBLUE_API_KEY = "${var.environment}/${var.service_name}/SENDINBLUE_API_KEY"
    },
    {
      SONGWHIP_AUTH_JWT_SECRET = "${var.environment}/${var.service_name}/SONGWHIP_AUTH_JWT_SECRET"
    },
    {
      SONGWHIP_WEBHOOK_KEY = "${var.environment}/${var.service_name}/SONGWHIP_WEBHOOK_KEY"
    },
    {
      STRIPE_PRIVATE_KEY = "${var.environment}/${var.service_name}/STRIPE_PRIVATE_KEY"
    },
    {
      STRIPE_WEBHOOK_SECRET = "${var.environment}/${var.service_name}/STRIPE_WEBHOOK_SECRET"
    },
    {
      SPLIT_API_KEY = "${var.environment}/${var.service_name}/SPLIT_API_KEY"
    },
    {
      CLOUDFLARE_TOKEN = "${var.environment}/${var.service_name}/CLOUDFLARE_TOKEN"
    },
    {
      CLOUDFLARE_ACCOUNT_TOKEN = "${var.environment}/${var.service_name}/CLOUDFLARE_ACCOUNT_TOKEN"
    },
    {
      TICKETMASTER_API_KEY = "${var.environment}/${var.service_name}/TICKETMASTER_API_KEY"
    },
    {
      SONGWHIP_RELEASE_TASKS_API_KEY = "${var.environment}/${var.service_name}/SONGWHIP_RELEASE_TASKS_API_KEY"
    },
    {
      SONGWHIP_QUEUE_API_KEY = "${var.environment}/${var.service_name}/SONGWHIP_QUEUE_API_KEY"
    },
    {
      SONGWHIP_EMAIL_API_KEY = "${var.environment}/${var.service_name}/SONGWHIP_EMAIL_API_KEY"
    },
    {
      SONGWHIP_LOOKUP_API_KEY = "${var.environment}/${var.service_name}/SONGWHIP_LOOKUP_API_KEY"
    },
    {
      SONGWHIP_AE_API_KEY = "${var.environment}/${var.service_name}/SONGWHIP_AE_API_KEY"
    },
    {
      INTERCOM_IDENTITY_SECRET = "${var.environment}/${var.service_name}/INTERCOM_IDENTITY_SECRET"
    },
    {
      SONGWHIP_STAGING_WEBHOOK_KEY = "${var.environment}/${var.service_name}/SONGWHIP_STAGING_WEBHOOK_KEY"
    },
    {
      SONGWHIP_GUARDIAN_REVIEW_SECRET = "${var.environment}/${var.service_name}/SONGWHIP_GUARDIAN_REVIEW_SECRET"
    },
    {
      HLS_CLOUDFRONT_PRIVATE_KEY = "${var.environment}/${var.service_name}/HLS_CLOUDFRONT_PRIVATE_KEY"
    },
    {
      AE_API_TOKEN = "${var.environment}/${var.service_name}/AE_API_TOKEN"
    }
  ]
}

module "songwhip_api_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 = 30
}

module "fargate_service_dashboard" {
  source                       = "git@github.com:theorchard/terraform-datadog.git//modules/service?ref=6.17.1"
  environment                  = var.environment
  environment_type             = "fargate"
  service_name                 = var.service_name
  application_family           = var.application_family
  service_4xx_monitor_enabled  = false
  service_5xx_monitor_enabled  = true
  critical_number_4xx          = 50
  critical_number_5xx          = 50
  critical_recovery_number_5xx = 45
  warning_number_5xx           = 45
  warning_recovery_number_5xx  = 40

  notification_endpoints            = "@slack-songwhip-alerts"
  escalation_notification_endpoints = "@slack-songwhip-private"
}

data "cloudflare_zone" "cloudflare_cloudflare_zone" {
  name       = var.cloudflare_zone
  account_id = var.cloudflare_account_id
}

# Add cloudfare songwhip-api elb cname record
resource "cloudflare_record" "prod_songwhip_api_alb_cname_record" {
  zone_id = data.cloudflare_zone.cloudflare_cloudflare_zone.id
  name    = "${var.environment}-songwhip-api-alb"
  value   = module.songwhip_api_fargate_environment.fargate_load_balancer_dns_name
  type    = "CNAME"
  proxied = true
}

resource "cloudflare_record" "songwhip_api_alb_cname_record" {
  zone_id = data.cloudflare_zone.cloudflare_cloudflare_zone.id
  name    = "api"
  value   = module.songwhip_api_fargate_environment.fargate_load_balancer_dns_name
  type    = "CNAME"
  proxied = true
}
