# Default 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
}

# AWS Provider
provider "aws" {
  region = var.aws_region

  default_tags {
    tags = module.default_tags.tags
  }
}

# Terraform Backend
terraform {
  backend "s3" {
    bucket  = "dev-orcd-terraform-state"
    key     = "dev/lambda-rdx-schema-registry/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

# Data Sources
data "aws_caller_identity" "current" {}

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

  environment = var.environment
}

# =============================================================================
# S3 Bucket for Schema Storage
# =============================================================================
module "schema_bucket" {
  source = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.15.7"

  env                = var.environment
  bucket_name        = var.schema_bucket_name
  application_family = var.application_family

  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  enable_guardduty_malware_protection = true
}

# S3 Datadog Monitoring
module "schema_bucket_datadog" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/s3?ref=6.18.2"

  environment                       = var.environment
  service_name                      = var.schema_bucket_name
  application_family                = var.application_family
  teams                             = [var.team_name]
  notification_endpoints            = var.notification_endpoints
  escalation_notification_endpoints = var.notification_endpoints

  dashboard_configuration = {
    enabled                       = false
    show_advanced_storage_metrics = false
    show_replication_metrics      = false
    show_standard_storage_metrics = false
  }

  guardduty_malware_monitor_configuration = {
    enabled = true
  }
}

# =============================================================================
# Secrets Manager
# =============================================================================
module "secrets" {
  source   = "git@github.com:theorchard/terraform-secrets-manager.git//?ref=1.5.2"
  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
}

# =============================================================================
# Sentry Projects
# =============================================================================
module "schema_introspection_sentry" {
  source = "git@github.com:theorchard/terraform-sentry.git//?ref=5.0.0"

  environment        = var.environment
  platform           = "node"
  service_name       = "lambda-rdx-introspection"
  application_family = var.application_family
  teams              = [var.environment]
}

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

  environment        = var.environment
  platform           = "node"
  service_name       = "lambda-rdx-composition"
  application_family = var.application_family
  teams              = [var.environment]
}

# =============================================================================
# IAM Policies for Lambda Functions
# =============================================================================

# S3 Access Policy
data "aws_iam_policy_document" "s3_access_policy_document" {
  statement {
    sid    = "AllowS3ObjectAccess"
    effect = "Allow"
    actions = [
      "s3:GetObject",
      "s3:PutObject"
    ]
    resources = [
      "${module.schema_bucket.s3_bucket_arn_output}/*"
    ]
  }

  statement {
    sid    = "AllowS3BucketList"
    effect = "Allow"
    actions = [
      "s3:ListBucket"
    ]
    resources = [
      module.schema_bucket.s3_bucket_arn_output
    ]
  }
}

resource "aws_iam_policy" "s3_access_policy" {
  name        = "S3-${module.schema_bucket.s3_bucket_name_output}-RW"
  description = "S3 access policy for ${var.service_name} Lambda functions"
  policy      = data.aws_iam_policy_document.s3_access_policy_document.json
  tags        = module.default_tags.tags
}

# Secrets Manager Access Policy
data "aws_iam_policy_document" "secrets_access_policy_document" {
  statement {
    sid    = "AllowSecretsManagerAccess"
    effect = "Allow"
    actions = [
      "secretsmanager:GetSecretValue"
    ]
    resources = values(module.secrets)[*].secret_arn
  }
}

resource "aws_iam_policy" "secrets_access_policy" {
  name        = "${var.environment}-${var.service_name}-secrets-access"
  description = "Secrets Manager access policy for ${var.service_name} Lambda functions"
  policy      = data.aws_iam_policy_document.secrets_access_policy_document.json
  tags        = module.default_tags.tags
}

# =============================================================================
# Lambda Function: Schema Introspection
# =============================================================================
module "schema_introspection_lambda" {
  source = "git@github.com:theorchard/terraform-lambda.git//?ref=5.3.0"

  environment        = var.environment
  lambda_name        = "lambda-${var.service_name}-schema-introspection"
  lambda_description = "Introspects GraphQL subgraphs and stores their schemas in S3"
  application_family = var.application_family

  use_container_image = true

  lambda_function_timeout                        = var.schema_introspection_timeout
  lambda_function_memory_size                    = var.schema_introspection_memory_size
  lambda_function_reserved_concurrent_executions = 1

  vpc_enabled    = true
  vpc_id         = module.vpc_info.vpc_id
  vpc_subnet_ids = module.vpc_info.default_private_subnet_ids

  sqs_event_enabled = false
  dlq_enabled       = false
  datadog_enabled   = true

  cloudwatch_event_enabled  = var.eventbridge_schedule_enabled
  cloudwatch_event_rules = [
    {
      name     = "lambda-${var.service_name}-schema-introspection"
      schedule = "rate(6 hours)"
      input    = jsonencode({ environment = var.rdx_environment })
    }
  ]

  iam_managed_policy_attachments = [
    aws_iam_policy.s3_access_policy.arn,
    aws_iam_policy.secrets_access_policy.arn,
  ]

  lambda_function_environment_variables = {
    ENV_NAME           = var.environment
    NODE_ENV           = var.environment
    AWS_REGION_NAME    = var.aws_region
    LOGGER_LEVEL       = var.logger_level
    SCHEMA_BUCKET      = module.schema_bucket.s3_bucket_name_output
    USM_TOKEN_ENDPOINT = var.usm_token_endpoint
    SENTRY_DSN         = module.schema_introspection_sentry.sentry_key_dsn_public_output
  }
}

# Schema Introspection Datadog Dashboard
module "schema_introspection_datadog" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/lambda?ref=6.18.2"

  environment                       = var.environment
  service_name                      = "lambda-${var.service_name}-schema-introspection"
  notification_endpoints            = var.notification_endpoints
  escalation_notification_endpoints = var.notification_endpoints
}

# =============================================================================
# Lambda Function: Schema Composition
# =============================================================================
module "schema_composition_lambda" {
  source = "git@github.com:theorchard/terraform-lambda.git//?ref=5.3.0"

  environment        = var.environment
  lambda_name        = "lambda-${var.service_name}-schema-composition"
  lambda_description = "Composes federated schema from stored subgraph schemas"
  application_family = var.application_family

  use_container_image = true

  lambda_function_timeout                        = var.schema_composition_timeout
  lambda_function_memory_size                    = var.schema_composition_memory_size
  lambda_function_reserved_concurrent_executions = 1

  vpc_enabled    = true
  vpc_id         = module.vpc_info.vpc_id
  vpc_subnet_ids = module.vpc_info.default_private_subnet_ids

  sqs_event_enabled    = false
  dlq_enabled          = false
  datadog_enabled      = true
  s3_event_enabled     = true
  s3_event_bucket_name = module.schema_bucket.s3_bucket_name_output

  iam_managed_policy_attachments = [
    aws_iam_policy.s3_access_policy.arn,
  ]

  lambda_function_environment_variables = {
    ENV_NAME        = var.environment
    NODE_ENV        = var.environment
    AWS_REGION_NAME = var.aws_region
    LOGGER_LEVEL    = var.logger_level
    SCHEMA_BUCKET   = module.schema_bucket.s3_bucket_name_output
    SENTRY_DSN      = module.schema_composition_sentry.sentry_key_dsn_public_output
  }
}

# S3 Notification to trigger Schema Composition when schemas are uploaded
resource "aws_s3_bucket_notification" "schema_bucket_notification" {
  bucket = module.schema_bucket.s3_bucket_name_output

  lambda_function {
    lambda_function_arn = module.schema_composition_lambda.lambda_arn
    events              = ["s3:ObjectCreated:*"]
    filter_prefix       = "${var.rdx_environment}/subgraphs/"
    filter_suffix       = ".graphql"
  }

  depends_on = [module.schema_composition_lambda]
}

# Schema Composition Datadog Dashboard
module "schema_composition_datadog" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/lambda?ref=6.18.2"

  environment                       = var.environment
  service_name                      = "lambda-${var.service_name}-schema-composition"
  notification_endpoints            = var.notification_endpoints
  escalation_notification_endpoints = var.notification_endpoints
}


