locals {
  sli_bucket_name          = "tidbcloud-sli-data-${var.env}-${var.logical_region_name}"
  firehose_stream_name     = "tidbcloud-sli-delivery-stream-${var.env}-${var.logical_region_name}"
  firehose_log_group_name  = "/aws/kinesisfirehose/${local.firehose_stream_name}"
  firehose_role_arn        = "arn:aws:iam::${local.aws_account_id}:role/tidbcloud-sli-firehose-role"
  firehose_log_stream_name = "DestinationDelivery"
  glue_database_name       = local.sli_bucket_name
  glue_table_name          = local.sli_bucket_name
}

# NOTE: This bucket must be emptied manually before `terraform destroy`.
# AWS refuses to delete non-empty buckets, causing the destroy to fail.
resource "aws_s3_bucket" "sli" {
  bucket = local.sli_bucket_name
  tags = merge({
    tidbcloud-auto-deploy-owner = local.eks.name
  }, var.tags)
}

resource "aws_s3_bucket_lifecycle_configuration" "sli" {
  bucket = aws_s3_bucket.sli.id

  rule {
    id = "SLI-Data-Retention-2Years"

    filter {}

    expiration {
      days = 730
    }

    abort_incomplete_multipart_upload {
      days_after_initiation = 7
    }

    status = "Enabled"
  }
}

resource "aws_glue_catalog_database" "sli" {
  name = local.glue_database_name

  tags = local.o11y_shoot_tags
}

resource "aws_glue_catalog_table" "sli" {
  depends_on = [aws_glue_catalog_database.sli]

  name          = local.glue_table_name
  database_name = local.glue_database_name

  table_type = "EXTERNAL_TABLE"

  storage_descriptor {
    location      = "s3://${aws_s3_bucket.sli.id}/"
    input_format  = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat"
    output_format = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat"

    ser_de_info {
      serialization_library = "org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe"

      parameters = {
        "serialization.format" = 1
      }
    }

    columns {
      name = "timestamp"
      type = "bigint"
    }

    columns {
      name = "instance"
      type = "string"
    }

    columns {
      name = "metrics"
      type = "string"
    }

    columns {
      name = "signature"
      type = "string"
    }
  }
}

resource "aws_cloudwatch_log_group" "sli" {
  name = local.firehose_log_group_name

  retention_in_days = 180

  tags = merge({
    tidbcloud-auto-deploy-owner = local.eks.name
  }, var.tags)
}

resource "aws_cloudwatch_log_stream" "sli" {
  name           = local.firehose_log_stream_name
  log_group_name = aws_cloudwatch_log_group.sli.name
}

resource "aws_kinesis_firehose_delivery_stream" "sli" {
  name        = local.firehose_stream_name
  destination = "extended_s3"

  extended_s3_configuration {
    role_arn   = local.firehose_role_arn
    bucket_arn = aws_s3_bucket.sli.arn

    buffering_interval = 60
    buffering_size     = 64

    cloudwatch_logging_options {
      enabled         = true
      log_group_name  = aws_cloudwatch_log_group.sli.name
      log_stream_name = aws_cloudwatch_log_stream.sli.name
    }

    compression_format = "UNCOMPRESSED"

    data_format_conversion_configuration {
      enabled = true
      input_format_configuration {
        deserializer {
          open_x_json_ser_de {}
        }
      }
      output_format_configuration {
        serializer {
          parquet_ser_de {}
        }
      }
      schema_configuration {
        database_name = aws_glue_catalog_database.sli.name
        region        = var.aws_region
        role_arn      = local.firehose_role_arn
        table_name    = aws_glue_catalog_table.sli.name
        version_id    = "LATEST"
      }
    }

    dynamic_partitioning_configuration {
      enabled        = true
      retry_duration = 300
    }

    processing_configuration {
      enabled = true
      processors {
        type = "MetadataExtraction"
        parameters {
          parameter_name  = "JsonParsingEngine"
          parameter_value = "JQ-1.6"
        }
        parameters {
          parameter_name = "MetadataExtractionQuery"
          parameter_value = jsonencode({
            metrics = ".metrics.name"
            year    = "(.timestamp | strftime(\"%Y\"))"
            month   = "(.timestamp | strftime(\"%m\"))"
            day     = "(.timestamp | strftime(\"%d\"))"
            hour    = "(.timestamp | strftime(\"%H\"))"
            minute  = "(.timestamp | strftime(\"%M\"))"
          })
        }
      }
    }
    prefix = join("/", [
      "metrics=!{partitionKeyFromQuery:metrics}",
      "year=!{partitionKeyFromQuery:year}",
      "month=!{partitionKeyFromQuery:month}",
      "day=!{partitionKeyFromQuery:day}",
      "hour=!{partitionKeyFromQuery:hour}",
      "minute=!{partitionKeyFromQuery:minute}",
      "",
    ])
    error_output_prefix = join("/", [
      "errors",
      "year=!{timestamp:yyyy}",
      "month=!{timestamp:MM}",
      "day=!{timestamp:dd}",
      "hour=!{timestamp:HH}",
      "!{firehose:error-output-type}",
    ])
  }

  tags = merge({
    tidbcloud-auto-deploy-owner = local.eks.name
  }, var.tags)
}
