require 'aws-crt'
require 'aws-sdk-s3'
require 'digest'
require 'logger'

# --- Configuration ---
# Replace with your bucket name
BUCKET_NAME = 'test-crc64nvme-ruby'
# The key (filename) for the object in S3
OBJECT_KEY = 'ruby-multipart-crc64nvme'
# --- End of Configuration ---

logger = Logger.new($stdout)

# Ensure your AWS credentials and region are configured
# (e.g., via environment variables or a credentials file)
s3_client = Aws::S3::Client.new()

begin
  logger.info("Initializing multipart upload for #{OBJECT_KEY} in bucket #{BUCKET_NAME}...")
  create_multipart_upload_response = s3_client.create_multipart_upload({
    bucket: BUCKET_NAME,
    key: OBJECT_KEY,
    checksum_algorithm: 'CRC64NVME'
  })
  upload_id = create_multipart_upload_response.upload_id
  logger.info("Multipart upload initiated with Upload ID: #{upload_id}")

  part1_data = 'A' * 5 * 1024 * 1024
  part2_data = 'B' * 5 * 1024 * 1024

  completed_parts = []

  logger.info('Uploading part 1...')
  upload_part1_response = s3_client.upload_part({
    bucket: BUCKET_NAME,
    key: OBJECT_KEY,
    part_number: 1,
    upload_id: upload_id,
    body: part1_data,
    checksum_algorithm: 'CRC64NVME'
  })
  completed_parts << {
    part_number: 1,
    etag: upload_part1_response.etag,
    checksum_crc64: upload_part1_response.checksum_crc64nvme
  }
  logger.info("Part 1 uploaded. ETag: #{upload_part1_response.etag}, CRC64NVME: #{upload_part1_response.checksum_crc64nvme}")

  logger.info('Uploading part 2...')
  upload_part2_response = s3_client.upload_part({
    bucket: BUCKET_NAME,
    key: OBJECT_KEY,
    part_number: 2,
    upload_id: upload_id,
    body: part2_data,
    checksum_algorithm: 'CRC64NVME'
  })
  completed_parts << {
    part_number: 2,
    etag: upload_part2_response.etag,
    checksum_crc64: upload_part2_response.checksum_crc64nvme
  }
  logger.info("Part 2 uploaded. ETag: #{upload_part2_response.etag}, CRC64NVME: #{upload_part2_response.checksum_crc64nvme}")

  logger.info('Completing the multipart upload...')
  s3_client.complete_multipart_upload({
    bucket: BUCKET_NAME,
    key: OBJECT_KEY,
    upload_id: upload_id,
    multipart_upload: {
      parts: completed_parts.map { |p| { part_number: p[:part_number], etag: p[:etag] } }
    }
  })
  logger.info('Multipart upload completed successfully.')

  logger.info("Performing a HeadObject request for #{OBJECT_KEY}...")
  head_object_response = s3_client.head_object({
    bucket: BUCKET_NAME,
    key: OBJECT_KEY,
    checksum_mode: 'ENABLED'
  })
  logger.info('HeadObject response:')
  logger.info("  ETag: #{head_object_response.etag}")
  logger.info("  Content-Length: #{head_object_response.content_length}")
  logger.info("  Last-Modified: #{head_object_response.last_modified}")
  logger.info("  Checksum CRC64NVME: #{head_object_response.checksum_crc64nvme}")

rescue Aws::S3::Errors::ServiceError => e
  logger.error("An S3 error occurred: #{e.message}")
  if upload_id
    logger.warn("Aborting multipart upload with ID: #{upload_id}")
    s3_client.abort_multipart_upload({
      bucket: BUCKET_NAME,
      key: OBJECT_KEY,
      upload_id: upload_id
    })
    logger.info('Multipart upload aborted.')
  end
rescue StandardError => e
  logger.error("An unexpected error occurred: #{e.message}")
end