import boto3
from botocore.exceptions import ClientError
import time

# A script to create an Organizational Unit (OU) in AWS Organizations using Boto3.
# This script assumes your AWS account is already part of an AWS Organization.

# --- Configuration ---
REGION = "us-east-1"
OU_NAME = "MyBoto3OU"

organizations_client = boto3.client('organizations', region_name=REGION)

def get_organization_root_id():
    """Gets the ID of the organization's root."""
    print("--- Getting Organization Root ID ---")
    try:
        response = organizations_client.list_roots()
        if not response['Roots']:
            raise Exception("No AWS Organization root found. Please ensure your account is part of an Organization.")
        root_id = response['Roots'][0]['Id']
        print(f"Organization Root ID: {root_id}")
        return root_id
    except ClientError as e:
        print(f"Error getting organization root ID: {e}")
        raise

def create_organizational_unit(root_id):
    """Creates an Organizational Unit."""
    print(f"\n--- Creating Organizational Unit: {OU_NAME} ---")
    try:
        response = organizations_client.create_organizational_unit(
            ParentId=root_id,
            Name=OU_NAME
        )
        ou_id = response['OrganizationalUnit']['Id']
        print(f"Organizational Unit created with ID: {ou_id}")
        return ou_id
    except ClientError as e:
        if e.response['Error']['Code'] == 'DuplicateOrganizationalUnitException':
            print(f"Organizational Unit '{OU_NAME}' already exists. Skipping creation.")
            response = organizations_client.list_organizational_units_for_parent(ParentId=root_id)
            for ou in response['OrganizationalUnits']:
                if ou['Name'] == OU_NAME:
                    return ou['Id']
            raise Exception("Could not find existing OU.")
        else:
            print(f"Error creating OU: {e}")
            raise

def delete_organizational_unit(ou_id):
    """Deletes the Organizational Unit."""
    print(f"\n--- Deleting Organizational Unit '{ou_id}' ---")
    try:
        organizations_client.delete_organizational_unit(OrganizationalUnitId=ou_id)
        print("Organizational Unit deleted.")
    except ClientError as e:
        if e.response['Error']['Code'] == 'OrganizationalUnitNotFoundException':
            print(f"Organizational Unit '{ou_id}' not found, skipping deletion.")
        elif e.response['Error']['Code'] == 'OrganizationalUnitNotEmptyException':
            print(f"Organizational Unit '{ou_id}' is not empty. Please move or delete accounts/OUs within it before deleting.")
        else:
            print(f"Error deleting OU: {e}")
            raise

def main():
    ou_id = None
    try:
        root_id = get_organization_root_id()
        ou_id = create_organizational_unit(root_id)

        print("\n--- AWS Organizations OU Setup Complete! ---")
        print(f"Organizational Unit ID: {ou_id}")
        print("You can now move accounts into this OU or attach policies to it.")

        input("Press Enter to delete the Organizational Unit...")

    except ClientError as e:
        print(f"An AWS client error occurred: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
    finally:
        if ou_id:
            delete_organizational_unit(ou_id)
        print("\n--- AWS Organizations demonstration and cleanup complete ---")

if __name__ == "__main__":
    main()
