terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
  }
}

provider "aws" {
  region = var.region
}

locals {
  common_tags = {
    managed_by = "terragrunt"
    unit       = "ingestion/extract/tidbcloud"
    source     = var.source_name
  }
}

# ---------------------------------------------------------------------------
# Data bucket: transient Parquet snapshots (sensitive). Written by TiDB Cloud
# export, read by the loader. Short lifecycle - raw Cloud Lake is the durable copy.
# ---------------------------------------------------------------------------
resource "aws_s3_bucket" "data" {
  bucket = var.data_bucket
  tags   = merge(local.common_tags, { role = "export-data", sensitivity = "high" })
}

resource "aws_s3_bucket_public_access_block" "data" {
  bucket                  = aws_s3_bucket.data.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_server_side_encryption_configuration" "data" {
  bucket = aws_s3_bucket.data.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

resource "aws_s3_bucket_lifecycle_configuration" "data" {
  bucket = aws_s3_bucket.data.id
  rule {
    id     = "expire-snapshots"
    status = "Enabled"
    filter {
      prefix = "${var.snapshot_prefix}/"
    }
    expiration {
      days = var.snapshot_expire_days
    }
    abort_incomplete_multipart_upload {
      days_after_initiation = 3
    }
  }
}

# ---------------------------------------------------------------------------
# Metadata bucket: durable manifests + runtime logs (low sensitivity).
# Written by the operator profile; the export IAM user has no access here.
# ---------------------------------------------------------------------------
resource "aws_s3_bucket" "metadata" {
  bucket = var.metadata_bucket
  tags   = merge(local.common_tags, { role = "export-metadata", sensitivity = "low" })
}

resource "aws_s3_bucket_public_access_block" "metadata" {
  bucket                  = aws_s3_bucket.metadata.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_server_side_encryption_configuration" "metadata" {
  bucket = aws_s3_bucket.metadata.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

resource "aws_s3_bucket_lifecycle_configuration" "metadata" {
  bucket = aws_s3_bucket.metadata.id
  rule {
    id     = "expire-manifests"
    status = "Enabled"
    filter {
      prefix = "${var.manifest_prefix}/"
    }
    expiration {
      days = var.metadata_expire_days
    }
  }
  rule {
    id     = "expire-logs"
    status = "Enabled"
    filter {
      prefix = "${var.log_prefix}/"
    }
    expiration {
      days = var.metadata_expire_days
    }
  }
}

# ---------------------------------------------------------------------------
# IAM: export writer (keys held by TiDB Cloud) - write only to the data bucket.
# ---------------------------------------------------------------------------
resource "aws_iam_user" "export_writer" {
  name = "${var.source_name}-tidb-export-writer"
  tags = local.common_tags
}

resource "aws_iam_user_policy" "export_writer" {
  name = "write-snapshots"
  user = aws_iam_user.export_writer.name
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid      = "ListDataBucket"
        Effect   = "Allow"
        Action   = ["s3:ListBucket", "s3:GetBucketLocation"]
        Resource = aws_s3_bucket.data.arn
      },
      {
        Sid      = "WriteSnapshots"
        Effect   = "Allow"
        Action   = ["s3:PutObject", "s3:AbortMultipartUpload"]
        Resource = "${aws_s3_bucket.data.arn}/${var.snapshot_prefix}/*"
      },
    ]
  })
}

resource "aws_iam_access_key" "export_writer" {
  user = aws_iam_user.export_writer.name
}

# ---------------------------------------------------------------------------
# IAM: loader reader (keys used by the s3_bulk_load COPY INTO) - read only.
# ---------------------------------------------------------------------------
resource "aws_iam_user" "loader_reader" {
  name = "${var.source_name}-s3-loader-reader"
  tags = local.common_tags
}

resource "aws_iam_user_policy" "loader_reader" {
  name = "read-snapshots"
  user = aws_iam_user.loader_reader.name
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid      = "ListDataBucket"
        Effect   = "Allow"
        Action   = ["s3:ListBucket", "s3:GetBucketLocation"]
        Resource = aws_s3_bucket.data.arn
      },
      {
        Sid      = "ReadSnapshots"
        Effect   = "Allow"
        Action   = ["s3:GetObject"]
        Resource = "${aws_s3_bucket.data.arn}/${var.snapshot_prefix}/*"
      },
    ]
  })
}

resource "aws_iam_access_key" "loader_reader" {
  user = aws_iam_user.loader_reader.name
}
