import boto3
from botocore.exceptions import ClientError
import time
import uuid

# A script to create a Global Accelerator using Boto3.

# --- Configuration ---
REGION = "us-east-1" # Global Accelerator is a global service, but endpoint groups are regional.
ACCELERATOR_NAME = "MyBoto3GlobalAccelerator"
LISTENER_PORT = 80
ENDPOINT_GROUP_REGION = "us-east-1" # Example region for the endpoint group

globalaccelerator_client = boto3.client('globalaccelerator', region_name=REGION)

def create_accelerator():
    """Creates a Global Accelerator."""
    print(f"--- Creating Global Accelerator: {ACCELERATOR_NAME} ---")
    try:
        response = globalaccelerator_client.create_accelerator(
            Name=ACCELERATOR_NAME,
            IpAddressType='IPV4',
            Enabled=True
        )
        accelerator_arn = response['Accelerator']['AcceleratorArn']
        print(f"Global Accelerator created with ARN: {accelerator_arn}. Waiting for it to be deployed...")
        # There isn't a direct waiter for accelerator_deployed in boto3, so we poll
        while True:
            status_response = globalaccelerator_client.describe_accelerator(AcceleratorArn=accelerator_arn)
            status = status_response['Accelerator']['Status']
            if status == 'DEPLOYED':
                print("Global Accelerator is deployed.")
                break
            print(f"Accelerator status: {status}, waiting...")
            time.sleep(10)
        return accelerator_arn
    except ClientError as e:
        print(f"Error creating accelerator: {e}")
        raise

def create_listener(accelerator_arn):
    """Creates a listener for the accelerator."""
    print(f"\n--- Creating Listener for Accelerator ---")
    try:
        response = globalaccelerator_client.create_listener(
            AcceleratorArn=accelerator_arn,
            PortRanges=[{'FromPort': LISTENER_PORT, 'ToPort': LISTENER_PORT}],
            Protocol='TCP',
            ClientAffinity='NONE'
        )
        listener_arn = response['Listener']['ListenerArn']
        print(f"Listener created with ARN: {listener_arn}")
        return listener_arn
    except ClientError as e:
        print(f"Error creating listener: {e}")
        raise

def create_endpoint_group(listener_arn):
    """Creates an endpoint group for the listener."""
    print(f"\n--- Creating Endpoint Group in {ENDPOINT_GROUP_REGION} ---")
    # For this demo, we'll create an empty endpoint group.
    # In a real scenario, you would add actual endpoints like ALBs, EC2 instances, etc.
    try:
        response = globalaccelerator_client.create_endpoint_group(
            ListenerArn=listener_arn,
            EndpointGroupRegion=ENDPOINT_GROUP_REGION,
            TrafficDialPercentage=100
        )
        endpoint_group_arn = response['EndpointGroup']['EndpointGroupArn']
        print(f"Endpoint Group created with ARN: {endpoint_group_arn}")
        return endpoint_group_arn
    except ClientError as e:
        print(f"Error creating endpoint group: {e}")
        raise

def cleanup_resources(accelerator_arn, listener_arn, endpoint_group_arn):
    """Cleans up all created resources."""
    print(f"\n--- Cleaning up resources ---")

    # Delete Endpoint Group
    if endpoint_group_arn:
        print(f"Deleting Endpoint Group '{endpoint_group_arn}'...")
        try:
            globalaccelerator_client.delete_endpoint_group(EndpointGroupArn=endpoint_group_arn)
            print("Endpoint Group deleted.")
        except ClientError as e:
            if e.response['Error']['Code'] == 'EndpointGroupNotFoundException':
                print(f"Endpoint Group '{endpoint_group_arn}' not found, skipping deletion.")
            else:
                print(f"Error deleting endpoint group: {e}")

    # Delete Listener
    if listener_arn:
        print(f"Deleting Listener '{listener_arn}'...")
        try:
            globalaccelerator_client.delete_listener(ListenerArn=listener_arn)
            print("Listener deleted.")
        except ClientError as e:
            if e.response['Error']['Code'] == 'ListenerNotFoundException':
                print(f"Listener '{listener_arn}' not found, skipping deletion.")
            else:
                print(f"Error deleting listener: {e}")

    # Delete Accelerator
    if accelerator_arn:
        print(f"Deleting Accelerator '{accelerator_arn}'...")
        try:
            globalaccelerator_client.delete_accelerator(AcceleratorArn=accelerator_arn)
            print("Global Accelerator deleted.")
        except ClientError as e:
            if e.response['Error']['Code'] == 'AcceleratorNotFoundException':
                print(f"Accelerator '{accelerator_arn}' not found, skipping deletion.")
            else:
                print(f"Error deleting accelerator: {e}")

def main():
    accelerator_arn = None
    listener_arn = None
    endpoint_group_arn = None
    try:
        accelerator_arn = create_accelerator()
        listener_arn = create_listener(accelerator_arn)
        endpoint_group_arn = create_endpoint_group(listener_arn)

        accelerator_info = globalaccelerator_client.describe_accelerator(AcceleratorArn=accelerator_arn)
        accelerator_dns_name = accelerator_info['Accelerator']['DnsName']

        print("\n--- Global Accelerator Setup Complete! ---")
        print(f"Accelerator DNS Name: {accelerator_dns_name}")
        print("You can now configure your application to use this DNS name.")

        input("Press Enter to delete the Global Accelerator and clean up resources...")

    except ClientError as e:
        print(f"An AWS client error occurred: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
    finally:
        cleanup_resources(accelerator_arn, listener_arn, endpoint_group_arn)
        print("\n--- Global Accelerator demonstration and cleanup complete ---")

if __name__ == "__main__":
    main()
