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          = "tax-and-payments"
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = module.default_tags.tags
  }
}

provider "snowflake" {
  account_name = "delphi.us-east-1"
  role         = "PROD_ATLANTIS"
  preview_features_enabled = [
    "snowflake_user_authentication_policy_attachment_resource"
  ]
}

terraform {
  backend "s3" {
    bucket  = "qa-accounting-terraform-state"
    key     = "uat/documents/load-from-s3/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
}

module "s3_bucket" {
  source = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.15.6"

  env                 = var.environment
  bucket_name         = var.s3_bucket_name
  acceleration_status = "Enabled"
  application_family  = var.application_family
  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  lifecycle_rules_options_noncurrent_version_transition = [
    {
      prefix        = ""
      enabled       = true
      days          = 35
      storage_class = "STANDARD_IA"
    }
  ]
}

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

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

data "aws_iam_policy_document" "s3_input_bucket_policy" {
  statement {
    effect = "Allow"

    actions = [
      "s3:ListBucket",
      "s3:GetObjectVersion",
      "s3:GetObject",
      "s3:PutObject",
    ]

    resources = [
      module.s3_bucket.s3_bucket_arn_output,
      "${module.s3_bucket.s3_bucket_arn_output}/*",
    ]
  }
}

resource "aws_iam_policy" "s3_input_bucket_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-RW"
  description = "Read, Write access to lambda-documents-load-from-s3 bucket"
  policy      = data.aws_iam_policy_document.s3_input_bucket_policy.json
}

#################################
#
# lambda configuration
#
##################################
module "lambda_documents_load_from_s3" {
  source                   = "git@github.com:theorchard/terraform-lambda.git?ref=5.2.2"
  environment              = var.environment
  lambda_name              = var.service_name
  lambda_description       = "Load data from s3 bucket"
  datadog_enabled          = var.datadog_enabled
  datadog_advanced_enabled = var.datadog_advanced_enabled

  application_family = var.application_family

  #  lambda_function_provisioned_concurrent_executions = var.lambda_provisioned_concurrent_executions
  lambda_function_timeout = "900"
  use_container_image     = true

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


  lambda_function_environment_variables = {
    ENVIRONMENT         = var.environment
    BUCKET_NAME         = module.s3_bucket.s3_bucket_name_output
    SNOWFLAKE_ACCOUNT   = var.snowflake_account
    SNOWFLAKE_ROLE      = var.snowflake_role
    SNOWFLAKE_WAREHOUSE = var.snowflake_warehouse
    SNOWFLAKE_USER      = var.snowflake_user
    SNOWFLAKE_DATABASE  = var.snowflake_database
  }

  iam_managed_policy_attachments = [
    aws_iam_policy.s3_input_bucket_policy.arn,
    #module.lambda_documents_load_from_s3_owsrequest.policy_arn_output
  ]
}

resource "aws_lambda_permission" "allow_load_from_s3_lambda_execution_from_bucket" {
  statement_id  = "AllowExecutionFromS3Bucket"
  action        = "lambda:InvokeFunction"
  function_name = module.lambda_documents_load_from_s3.lambda_name
  principal     = "s3.amazonaws.com"
  source_arn    = module.s3_bucket.s3_bucket_arn_output
}

resource "aws_s3_bucket_notification" "load_from_s3_bucket_notification" {
  bucket = module.s3_bucket.s3_bucket_name_output

  dynamic "lambda_function" {
    for_each = local.lambda_notifications
    content {
      lambda_function_arn = module.lambda_documents_load_from_s3.lambda_arn
      events              = ["s3:ObjectCreated:CompleteMultipartUpload", "s3:ObjectCreated:Put"]
      filter_prefix       = lambda_function.value.prefix
      filter_suffix       = try(lambda_function.value.suffix, ".csv")
    }
  }

  depends_on = [aws_lambda_permission.allow_load_from_s3_lambda_execution_from_bucket]
}

#module "lambda_documents_load_from_s3_owsrequest" {
#  source = "git@github.com:theorchard/terraform-owsrequest.git?ref=1.1.0"
#
#  environment_name = var.environment
#  service_name     = var.service_name
#}

# create datadog dashboards.
module "datadog_lambda_documents_load_from_s3" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/lambda?ref=6.16.2"

  environment                       = var.environment
  service_name                      = var.service_name
  lambda_invocation_monitor_enabled = false

  notification_endpoints            = "@slack-tmp-uat-accounting-alerts"
  escalation_notification_endpoints = "@slack-tmp-uat-accounting-alerts"

  lambda_error_ok_number                = 0
  lambda_error_warning_recovery_number  = null
  lambda_error_critical_recovery_number = null
  lambda_error_warning_number           = null
  lambda_error_critical_number          = 1
}

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

  environment        = var.environment
  platform           = "python"
  service_name       = var.service_name
  teams              = ["abacus-qa"]
  application_family = var.application_family
}

data "aws_iam_policy_document" "load_from_s3_invoke_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "lambda:InvokeFunction",
      "lambda:GetFunction",
      "lambda:GetFunctionConfiguration",
      "lambda:GetPolicy",
      "lambda:GetAlias",
      "lambda:ListVersionsByFunction",
      "lambda:ListAliases",
      "lambda:GetFunctionEventInvokeConfig"
    ]
    resources = [
      module.lambda_documents_load_from_s3.lambda_arn
    ]
  }
}

resource "aws_iam_policy" "load_from_s3_invoke_policy" {
  name   = "${var.environment}-load-from-s3-invoke-policy"
  policy = data.aws_iam_policy_document.load_from_s3_invoke_policy_document.json
}
