data "aws_caller_identity" "current" {}

resource "aws_athena_database" "s3_inventory_db" {
  provider = aws.aws_us_east_2

  name          = "inventory_db"
  bucket        = module.inventory_results_bucket_aws_us_east_2.s3_bucket_name_output
  force_destroy = true

  encryption_configuration {
    encryption_option = "SSE_S3"
  }
}

resource "aws_glue_catalog_table" "inventory_table" {
  for_each = local.directories_us_east_1

  provider      = aws.aws_us_east_2
  name          = each.value
  database_name = aws_athena_database.s3_inventory_db.name
  catalog_id    = data.aws_caller_identity.current.account_id
  table_type    = "EXTERNAL_TABLE"
  parameters = {
    "projection.enabled"          = "true",
    "projection.dt.type"          = "date",
    "projection.dt.format"        = "yyyy-MM-dd-HH-mm",
    "projection.dt.range"         = "2024-01-01-00-00,NOW",
    "projection.dt.interval"      = "1",
    "projection.dt.interval.unit" = "HOURS"
  }

  partition_keys {
    name = "dt"
    type = "string"
  }

  storage_descriptor {
    location      = "s3://pde-inventory-us-east-1/${each.value}/default_entire_bucket_daily_parquet/hive/"
    input_format  = "org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat"
    output_format = "org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat"

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

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

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

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

    columns {
      name = "is_latest"
      type = "boolean"
    }

    columns {
      name = "is_delete_marker"
      type = "boolean"
    }

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

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

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

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

    columns {
      name = "is_multipart_uploaded"
      type = "boolean"
    }

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

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

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

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

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

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

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

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

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

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

resource "aws_glue_catalog_table" "inventory_table_us_east_2" {
  for_each = local.directories_us_east_2

  provider      = aws.aws_us_east_2
  name          = each.value
  database_name = aws_athena_database.s3_inventory_db.name
  catalog_id    = data.aws_caller_identity.current.account_id
  table_type    = "EXTERNAL_TABLE"
  parameters = {
    "projection.enabled"          = "true",
    "projection.dt.type"          = "date",
    "projection.dt.format"        = "yyyy-MM-dd-HH-mm",
    "projection.dt.range"         = "2024-01-01-00-00,NOW",
    "projection.dt.interval"      = "1",
    "projection.dt.interval.unit" = "HOURS"
  }

  partition_keys {
    name = "dt"
    type = "string"
  }

  storage_descriptor {
    location      = "s3://pde-inventory-us-east-2/${each.value}/default_entire_bucket_daily_parquet/hive/"
    input_format  = "org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat"
    output_format = "org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat"

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

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

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

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

    columns {
      name = "is_latest"
      type = "boolean"
    }

    columns {
      name = "is_delete_marker"
      type = "boolean"
    }

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

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

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

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

    columns {
      name = "is_multipart_uploaded"
      type = "boolean"
    }

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

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

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

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

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

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

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

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

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

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

resource "aws_glue_catalog_table" "inventory_table_us_west_2" {
  for_each = local.directories_us_west_2

  provider      = aws.aws_us_east_2
  name          = each.value
  database_name = aws_athena_database.s3_inventory_db.name
  catalog_id    = data.aws_caller_identity.current.account_id
  table_type    = "EXTERNAL_TABLE"
  parameters = {
    "projection.enabled"          = "true",
    "projection.dt.type"          = "date",
    "projection.dt.format"        = "yyyy-MM-dd-HH-mm",
    "projection.dt.range"         = "2024-01-01-00-00,NOW",
    "projection.dt.interval"      = "1",
    "projection.dt.interval.unit" = "HOURS"
  }

  partition_keys {
    name = "dt"
    type = "string"
  }

  storage_descriptor {
    location      = "s3://pde-inventory-us-west-2/${each.value}/default_entire_bucket_daily_parquet/hive/"
    input_format  = "org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat"
    output_format = "org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat"

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

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

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

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

    columns {
      name = "is_latest"
      type = "boolean"
    }

    columns {
      name = "is_delete_marker"
      type = "boolean"
    }

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

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

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

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

    columns {
      name = "is_multipart_uploaded"
      type = "boolean"
    }

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

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

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

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

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

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

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

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

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

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

resource "aws_athena_workgroup" "workgroup" {
  provider = aws.aws_us_east_2
  name     = "inventory_workgroup"
  configuration {
    result_configuration {
      output_location = "s3://${module.inventory_results_bucket_aws_us_east_2.s3_bucket_name_output}"

      encryption_configuration {
        encryption_option = "SSE_S3"
      }
    }
  }
}


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

  providers = {
    aws = aws.aws_us_east_2
  }

  env                   = var.environment
  bucket_name           = "pde-inventory-results"
  custom_bucket_name    = "pde-inventory-results"
  custom_logging_bucket = "backup-orcd-us-east-2-s3-logs"
  application_family    = var.application_family
  block_public_access   = true

  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  lifecycle_rules_options_noncurrent_version_transition = local.lifecycle_rules_options_noncurrent_version_transition
  lifecycle_rules_options_noncurrent_version_expiration = local.lifecycle_rules_options_noncurrent_version_expiration
  lifecycle_rules_options_current_version_transition    = local.lifecycle_rules_options_current_version_transition
  lifecycle_rules_options_current_version_expiration    = local.lifecycle_rules_options_current_version_expiration
}


data "aws_s3_objects" "inventory_us_east_1" {
  bucket    = module.inventory_bucket_aws_us_east_1.s3_bucket_name_output
  delimiter = "/"
  provider  = aws.aws_us_east_1
}

data "aws_s3_objects" "inventory_us_east_2" {
  bucket    = module.inventory_bucket_aws_us_east_2.s3_bucket_name_output
  delimiter = "/"
  provider  = aws.aws_us_east_2
}

data "aws_s3_objects" "inventory_us_west_2" {
  bucket    = module.inventory_bucket_aws_us_west_2.s3_bucket_name_output
  delimiter = "/"
  provider  = aws.aws_us_west_2
}

# Local variable to store processed directory names
locals {
  directories_us_east_1 = toset([
    for prefix in data.aws_s3_objects.inventory_us_east_1.common_prefixes :
    trimspace(trimsuffix(prefix, "/"))
    if trimspace(trimsuffix(prefix, "/")) != ""
  ])
  directories_us_east_2 = toset([
    for prefix in data.aws_s3_objects.inventory_us_east_2.common_prefixes :
    trimspace(trimsuffix(prefix, "/"))
    if trimspace(trimsuffix(prefix, "/")) != ""
  ])
  directories_us_west_2 = toset([
    for prefix in data.aws_s3_objects.inventory_us_west_2.common_prefixes :
    trimspace(trimsuffix(prefix, "/"))
    if trimspace(trimsuffix(prefix, "/")) != ""
  ])
}
