import random
import time
from azure.identity import ClientSecretCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.core.exceptions import ResourceExistsError
import time  # Added import for unique timestamp

# Azure Configuration
SUBSCRIPTION_ID = "e17c11f2-bd98-44bb-a489-e54776445215"
RESOURCE_GROUP = "BitzerHosting"
LOCATION = "eastus"

USERNAME = "MyGame"
PASSWORD = "AzureVM@2024!"

# Service Principal Credentials (REPLACE with yours)
TENANT_ID = "92a8c063-1f22-4598-9960-9dfccb91025c"
CLIENT_ID = "00379617-cde7-45dc-8d44-5e38198454e3"
CLIENT_SECRET = "CkM8Q~6~DSrGXnMbu4G_eLKTAb.UKxm5KpuJocCa"

# Image reference
IMAGE_GALLERY_NAME = "VM"
IMAGE_DEFINITION_NAME = "VM"
IMAGE_VERSION = "1.0.0"

def destroy_vm_and_resources(vm_name):
    credential = ClientSecretCredential(
        tenant_id=TENANT_ID,
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET
    )

    resource_client = ResourceManagementClient(credential, SUBSCRIPTION_ID)
    network_client = NetworkManagementClient(credential, SUBSCRIPTION_ID)
    compute_client = ComputeManagementClient(credential, SUBSCRIPTION_ID)

    print(f"Starting deletion of VM and associated resources for {vm_name}...")

    try:
        # Delete VM
        print(f"Deleting VM: {vm_name}...")
        compute_client.virtual_machines.begin_delete(RESOURCE_GROUP, vm_name).result()
        print("VM deleted.")

        # Delete Network Interface
        nic_name = f"{vm_name}-nic"
        print(f"Deleting Network Interface: {nic_name}...")
        network_client.network_interfaces.begin_delete(RESOURCE_GROUP, nic_name).result()
        print("Network Interface deleted.")

        # Delete Public IP Address
        public_ip_name = f"{vm_name}-ip"
        print(f"Deleting Public IP Address: {public_ip_name}...")
        network_client.public_ip_addresses.begin_delete(RESOURCE_GROUP, public_ip_name).result()
        print("Public IP deleted.")

        # Remove NSG association from subnet before deleting NSG
        print(f"Removing NSG association from subnet {vm_name}-subnet...")
        subnet = network_client.subnets.get(RESOURCE_GROUP, f"{vm_name}-vnet", f"{vm_name}-subnet")
        subnet.network_security_group = None
        network_client.subnets.begin_create_or_update(
            RESOURCE_GROUP,
            f"{vm_name}-vnet",
            f"{vm_name}-subnet",
            subnet
        ).result()
        print("NSG association removed from subnet.")

        # Delete Network Security Group
        nsg_name = f"{vm_name}-nsg"
        print(f"Deleting Network Security Group: {nsg_name}...")
        network_client.network_security_groups.begin_delete(RESOURCE_GROUP, nsg_name).result()
        print("NSG deleted.")

        # Delete Virtual Network (VNet)
        vnet_name = f"{vm_name}-vnet"
        print(f"Deleting Virtual Network: {vnet_name}...")
        network_client.virtual_networks.begin_delete(RESOURCE_GROUP, vnet_name).result()
        print("Virtual Network deleted.")

        # Delete OS Disk
        os_disk_name = f"{vm_name}-osdisk"
        print(f"Deleting OS Disk: {os_disk_name}...")
        compute_client.disks.begin_delete(RESOURCE_GROUP, os_disk_name).result()
        print("OS Disk deleted.")

        print(f"All resources for VM {vm_name} have been deleted successfully.")

    except Exception as e:
        print(f"Error during deletion: {e}")
   
def create_vm_from_custom_image():
    random.seed(time.time_ns())   # seed from high‑resolution clock
    VM_NAME = f"GameVM-{random.randint(1000,9999)}"
   
    credential = ClientSecretCredential(
        tenant_id=TENANT_ID,
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET
    )

    resource_client = ResourceManagementClient(credential, SUBSCRIPTION_ID)
    network_client = NetworkManagementClient(credential, SUBSCRIPTION_ID)
    compute_client = ComputeManagementClient(credential, SUBSCRIPTION_ID)

    # Ensure Resource Group exists
    resource_client.resource_groups.create_or_update(
        RESOURCE_GROUP, {"location": LOCATION}
    )

    print(" Creating public IP address...")
    public_ip = network_client.public_ip_addresses.begin_create_or_update(
        RESOURCE_GROUP,
        f"{VM_NAME}-ip",
        {
            "location": LOCATION,
            "sku": {"name": "Standard"},
            "public_ip_allocation_method": "Static"
        }
    ).result()

    print(" Configuring network security group...")
    nsg = network_client.network_security_groups.begin_create_or_update(
        RESOURCE_GROUP,
        f"{VM_NAME}-nsg",
        {
            "location": LOCATION,
            "security_rules": [
                {
                    "name": "allow-rdp",
                    "protocol": "Tcp",
                    "source_port_range": "*",
                    "destination_port_range": "3389",
                    "source_address_prefix": "*",
                    "destination_address_prefix": "*",
                    "access": "Allow",
                    "priority": 100,
                    "direction": "Inbound"
                },
                {
                    "name": "allow-http",
                    "protocol": "Tcp",
                    "source_port_range": "*",
                    "destination_port_range": "80",
                    "source_address_prefix": "*",
                    "destination_address_prefix": "*",
                    "access": "Allow",
                    "priority": 110,
                    "direction": "Inbound"
                },
                {
                    "name": "allow-https",
                    "protocol": "Tcp",
                    "source_port_range": "*",
                    "destination_port_range": "443",
                    "source_address_prefix": "*",
                    "destination_address_prefix": "*",
                    "access": "Allow",
                    "priority": 120,
                    "direction": "Inbound"
                },
                {
                    "name": "allow-8443",
                    "protocol": "Tcp",
                    "source_port_range": "*",
                    "destination_port_range": "8443",
                    "source_address_prefix": "*",
                    "destination_address_prefix": "*",
                    "access": "Allow",
                    "priority": 130,
                    "direction": "Inbound"
                }
            ]
        }
    ).result()

    print(" Creating virtual network and subnet...")
    vnet = network_client.virtual_networks.begin_create_or_update(
        RESOURCE_GROUP,
        f"{VM_NAME}-vnet",
        {
            "location": LOCATION,
            "address_space": {"address_prefixes": ["10.0.0.0/16"]}
        }
    ).result()

    subnet = network_client.subnets.begin_create_or_update(
        RESOURCE_GROUP,
        vnet.name,
        f"{VM_NAME}-subnet",
        {"address_prefix": "10.0.0.0/24", "network_security_group": {"id": nsg.id}}
    ).result()

    print(" Creating network interface...")
    nic = network_client.network_interfaces.begin_create_or_update(
        RESOURCE_GROUP,
        f"{VM_NAME}-nic",
        {
            "location": LOCATION,
            "ip_configurations": [{
                "name": "ipconfig1",
                "subnet": {"id": subnet.id},
                "public_ip_address": {"id": public_ip.id}
            }]
        }
    ).result()

    print(f" Creating VM {VM_NAME} from custom image version {IMAGE_VERSION}...")
    vm_parameters = {
        "location": LOCATION,
        "storage_profile": {
            "image_reference": {
                "id": f"/subscriptions/{SUBSCRIPTION_ID}/resourceGroups/{RESOURCE_GROUP}/providers/Microsoft.Compute/galleries/{IMAGE_GALLERY_NAME}/images/{IMAGE_DEFINITION_NAME}/versions/{IMAGE_VERSION}"
            },
            "os_disk": {
                "caching": "ReadWrite",
                "managed_disk": {"storage_account_type": "Premium_LRS"},
                "name": f"{VM_NAME}-osdisk",
                "create_option": "FromImage"
            }
        },
        "hardware_profile": {"vm_size": "Standard_D4s_v3"},
        "os_profile": {
            "computer_name": VM_NAME,
            "admin_username": USERNAME,
            "admin_password": PASSWORD,
            "windows_configuration": {
                "enable_automatic_updates": True,
                "provision_vm_agent": True
            }
        },
        "network_profile": {
            "network_interfaces": [{"id": nic.id, "primary": True}]
        },
        "security_profile": {
            "security_type": "TrustedLaunch",
            "uefi_settings": {
                "secure_boot_enabled": True,
                "v_tpm_enabled": True
            }
        }
    }

    vm = compute_client.virtual_machines.begin_create_or_update(
        RESOURCE_GROUP,
        VM_NAME,
        vm_parameters
    ).result()
    print(f" VM created successfully: {vm.name}")

    # Run batch file using Azure Run Command (RunPowerShellScript)
    print(f" Running batch file on VM {VM_NAME} using Run Command...")

    run_command_parameters = {
        'command_id': 'RunPowerShellScript',
        'script': [
            'cd "C:\\Program Files\\Data"',
            '.\\conf.bat > ".\\bat_output.txt" 2>&1'
        ]
    }

    # Start run command asynchronously without .result()
    compute_client.virtual_machines.begin_run_command(
        RESOURCE_GROUP,
        VM_NAME,
        run_command_parameters
    )

    print(f" Batch file execution started. Output will be stored in C:\\Program Files\\Data\\bat_output.txt")

    public_ip = network_client.public_ip_addresses.get(RESOURCE_GROUP, f"{VM_NAME}-ip")

    return {
        "vm_name": VM_NAME,
        "ip_address": public_ip.ip_address,
        "username": USERNAME,
        "password": PASSWORD,
        "message": "VM ready from custom image. Login with RDP."
    }

if __name__ == "__main__":

    # When you run `python index.py` manually, this block still works.

    try:
        info = create_vm_from_custom_image()
        print(" VM Deploy Info:", info)
    except Exception as e:
        print(" Fatal error:", e)