#!/bin/bash

# A script to create a CloudFront distribution for an S3 bucket using AWS CLI.

# --- Configuration ---
REGION="us-east-1"
RANDOM_SUFFIX=$(head /dev/urandom | tr -dc a-z0-9 | head -c 8)
S3_BUCKET_NAME="my-cli-cf-s3-origin-${RANDOM_SUFFIX}"
CF_DISTRIBUTION_COMMENT="My CLI CloudFront Distribution for S3"
OAC_NAME="MyCLICF_OAC"

# --- 1. Create S3 Bucket ---
echo "--- Creating S3 Bucket: $S3_BUCKET_NAME ---"
aws s3api create-bucket \
  --bucket $S3_BUCKET_NAME \
  --region $REGION

echo "S3 Bucket created."

# --- 2. Create Origin Access Control (OAC) ---
echo -e "\n--- Creating Origin Access Control (OAC) ---"
OAC_ID=$(aws cloudfront create-origin-access-control \
  --origin-access-control-config "Name=$OAC_NAME,SigningBehavior=no-override,SigningProtocol=sigv4,OriginAccessControlOriginType=s3" \
  --region $REGION \
  --query 'OriginAccessControl.Id' --output text)

echo "OAC created with ID: $OAC_ID"

# --- 3. Update S3 Bucket Policy to allow OAC access ---
echo -e "\n--- Updating S3 Bucket Policy for OAC access ---"
# Get the OAC ARN (needed for the bucket policy)
OAC_ARN=$(aws cloudfront get-origin-access-control \
  --id $OAC_ID \
  --region $REGION \
  --query 'OriginAccessControl.OriginAccessControlConfig.SigningBehavior' --output text | \
  awk -v oac_id="$OAC_ID" -v region="$REGION" -v account_id="$(aws sts get-caller-identity --query Account --output text)" '{print "arn:aws:iam::cloudfront:user/CloudFront Origin Access Control/" oac_id}')

# Construct the bucket policy
BUCKET_POLICY_JSON=$(cat <<-EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontServicePrincipalReadOnly",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::$S3_BUCKET_NAME/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::$(aws sts get-caller-identity --query Account --output text):distribution/*"
        }
      }
    }
  ]
}
EOF
)

aws s3api put-bucket-policy \
  --bucket $S3_BUCKET_NAME \
  --policy "$BUCKET_POLICY_JSON" \
  --region $REGION

echo "S3 Bucket Policy updated."

# --- 4. Create CloudFront Distribution ---
echo -e "\n--- Creating CloudFront Distribution ---"
DISTRIBUTION_ID=$(aws cloudfront create-distribution \
  --distribution-config "CallerReference=$(date +%s),Comment=$CF_DISTRIBUTION_COMMENT,Enabled=true,Origins={Quantity=1,Items=[{Id=S3Origin,DomainName=$S3_BUCKET_NAME.s3.$REGION.amazonaws.com,OriginAccessControlId=$OAC_ID,S3OriginConfig={OriginAccessIdentity=}}]},DefaultCacheBehavior={TargetOriginId=S3Origin,ViewerProtocolPolicy=redirect-to-https,AllowedMethods={Quantity=2,Items=[GET,HEAD],CachedMethods={Quantity=2,Items=[GET,HEAD]}},ForwardedValues={QueryString=false,Cookies={Forward=none}},MinTTL=0,DefaultTTL=86400,MaxTTL=31536000},ViewerCertificate={CloudFrontDefaultCertificate=true}" \
  --region $REGION \
  --query 'Distribution.Id' --output text)

echo "CloudFront Distribution created with ID: $DISTRIBUTION_ID. Waiting for it to deploy (this can take 10-15 minutes)..."
aws cloudfront wait distribution-deployed \
  --id $DISTRIBUTION_ID \
  --region $REGION

echo "CloudFront Distribution deployed."

# --- 5. Output CloudFront Domain Name ---
CF_DOMAIN_NAME=$(aws cloudfront get-distribution \
  --id $DISTRIBUTION_ID \
  --region $REGION \
  --query 'Distribution.DomainName' --output text)

echo -e "\n--- CloudFront Distribution Setup Complete! ---"
echo "CloudFront Domain Name: $CF_DOMAIN_NAME"
echo "You can now upload content to s3://$S3_BUCKET_NAME/ and access it via CloudFront."

read -p "Press Enter to delete the CloudFront distribution and clean up resources..."

# --- Clean Up ---
echo -e "\n--- Cleaning up resources ---"

# Disable and Delete CloudFront Distribution
echo "Disabling CloudFront Distribution '$DISTRIBUTION_ID' நான"
DISTRIBUTION_CONFIG_ETAG=$(aws cloudfront get-distribution-config \
  --id $DISTRIBUTION_ID \
  --region $REGION \
  --query 'ETag' --output text)

aws cloudfront update-distribution \
  --id $DISTRIBUTION_ID \
  --if-match $DISTRIBUTION_CONFIG_ETAG \
  --distribution-config "CallerReference=$(date +%s),Comment=$CF_DISTRIBUTION_COMMENT,Enabled=false,Origins={Quantity=1,Items=[{Id=S3Origin,DomainName=$S3_BUCKET_NAME.s3.$REGION.amazonaws.com,OriginAccessControlId=$OAC_ID,S3OriginConfig={OriginAccessIdentity=}}]},DefaultCacheBehavior={TargetOriginId=S3Origin,ViewerProtocolPolicy=redirect-to-https,AllowedMethods={Quantity=2,Items=[GET,HEAD],CachedMethods={Quantity=2,Items=[GET,HEAD]}},ForwardedValues={QueryString=false,Cookies={Forward=none}},MinTTL=0,DefaultTTL=86400,MaxTTL=31536000},ViewerCertificate={CloudFrontDefaultCertificate=true}" \
  --region $REGION

echo "Waiting for CloudFront Distribution to be disabled..."
aws cloudfront wait distribution-deployed \
  --id $DISTRIBUTION_ID \
  --region $REGION

echo "Deleting CloudFront Distribution '$DISTRIBUTION_ID' நான"
aws cloudfront delete-distribution \
  --id $DISTRIBUTION_ID \
  --region $REGION

echo "CloudFront Distribution deleted."

# Delete S3 Bucket
echo "Deleting S3 Bucket '$S3_BUCKET_NAME' நான"
aws s3 rb s3://$S3_BUCKET_NAME --force --region $REGION

echo "S3 Bucket deleted."

# Delete OAC
echo "Deleting OAC '$OAC_ID' நான"
aws cloudfront delete-origin-access-control \
  --id $OAC_ID \
  --if-match $(aws cloudfront get-origin-access-control --id $OAC_ID --region $REGION --query 'ETag' --output text) \
  --region $REGION

echo "OAC deleted."

echo -e "\n--- CloudFront demonstration and cleanup complete ---"
