#!/usr/bin/env herodo
// Production VM with Network Access
// This script starts an Ubuntu VM with internet connectivity and SSH access

// ============================================================================
// SETUP REQUIRED: Edit these paths for your environment
// ============================================================================
let ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa5srzZwh3ulajtY2EZ1SiPY1JNelcaP8O/FZqrnJi6OxAPijl0KzoNrzgemqxhAS/eIglBYbgQuw/Po15MtdMgXmfrtNgrZjQQtLxGFz5KmUbzawPGI7iRkN40LEo0y0hcGLV1G+YiNO+3YU7K5I+gos+04OUJe4HYjcp92nAEviqxa40po2f67KgP5xrZxaOpELZA/hIf1wCzCyTsdvu3k+hw1QlSTIso6WTcUw7LLssvxAs7JZ31kgx+L740xQJWsiVv/go3td0GuETfRSbfjBtOD/wIEHG5UtazOrR+8ukotqQ/ERWuyx1abaEKwro3fLunmjhfgDbnJYy7As1 ahmed@ahmed-Inspiron-3576";
// ============================================================================
let flist_path = "/tmp/ubuntu-24.04_systemd.fl";
let root_fs_dir = "/tmp/rootfs"; 
let virtio_socket = "/tmp/vhost-fs.sock";
let hero_init_disk_path = "/tmp/hero-init-complete.img";
let vm_mac = "42:91:5e:e6:fd:99";
let api_socket = "/tmp/ch-vm.sock";
let hostname = "production-vm";
let username = "testuser";


fn unpack_image(flist_path, root_fs_dir) {
    // Download the flist file if it doesn't exist
    print("📥 Checking flist file...");
    
    let flist_url = "http://185.69.167.83/flists/ubuntu-24.04_systemd.fl";
    
    // Download the flist file
    print("Downloading flist from: " + flist_url);
    let download_cmd = "wget -O " + flist_path + " " + flist_url;
    let download_result = run(download_cmd).run();
    
    if !download_result.success {
        print("❌ Failed to download flist file");
        print("Error: " + download_result.stderr);
        return;
    }
    
    print("✓ Flist downloaded successfully");
    
    // Mount myfs image at mount point
    print("📂 Attempting unpack...");
    let result = myfs_unpack(
        flist_path,           // flist_path
        root_fs_dir,          // mount_point
        "/tmp/myfs_cache"     // cache_path
    );
    
    print("Mount result: " + result);
    print("✓ Mount operation completed");
}


fn setup_network() {
    const RESOURCE_NAME = "vms";
    const MYCELIUM_SEED = "00112233445566778899aabbccddeeff20112233446566778899aabbccddeeff";
    const BRIDGE_IPV4 = "10.10.1.1/24";
    const OUTBOUND_IFACE = "wlp0s20f3";

    print("🌐 Setting up network...");
    try { delete_network_resource(RESOURCE_NAME); } catch { }

    let resource = create_network_resource(
        RESOURCE_NAME,
        MYCELIUM_SEED,
        BRIDGE_IPV4,
        OUTBOUND_IFACE
    );

    let vm1 = add_vm_to_resource(resource, "myvm");
    print("   ✓ Network configured");
    
    return vm1;
}


fn create_config(net_config, vm_mac, hostname, username, ssh_key, hero_init_disk_path) {
    print("💾 Creating hero-init disk...");
    
    let config = hero_init_config_new("prod-vm-001", hostname);

    // Calculate gateway IPs from network config
    let private_ip_parts = net_config.private_ip.split("/");
    let private_ip_addr = private_ip_parts[0];
    let private_ip_octets = private_ip_addr.split(".");
    let vm_ipv4_gateway = private_ip_octets[0] + "." + private_ip_octets[1] + "." + private_ip_octets[2] + ".1";

    let mycelium_ip_parts = net_config.mycelium_ip.split("/");
    let mycelium_ip_addr = mycelium_ip_parts[0];
    let mycelium_prefix = mycelium_ip_addr.split("::")[0];
    let vm_ipv6_gateway = mycelium_prefix + "::1";

    hero_init_config_add_user_with_ssh(config, username, true, ssh_key);

    let network = hero_init_network_new("netplan");
    hero_init_network_add_interface(network, "eth0", vm_mac, false);
    hero_init_network_interface_set_gateway4(network, "eth0", vm_ipv4_gateway);
    hero_init_network_interface_add_addresses(network, "eth0", [net_config.private_ip + "/24", net_config.mycelium_ip + "/64"]);
    hero_init_network_interface_add_route(network, "eth0", "400::/7", vm_ipv6_gateway);
    hero_init_network_interface_set_nameservers_with_search(network, "eth0", ["8.8.8.8", "8.8.4.4"], ["local"]);
    hero_init_config_set_network(config, network);

    let result = hero_init_create_complete_disk(hero_init_disk_path, 10, config);

    if result != "" {
        print("   ✓ Cloud-init disk created");
    } else {
        print("   ❌ Failed to create disk!");
    }
}


fn share_rootfs(root_dir, socket_path) {
    let temp_daemon = share_directory(root_dir, socket_path);
    print("📁 Sharing rootfs...");
    print("   ✓ VirtioFS daemon started");
}

fn run_vm(api_sock, root_dir, virt_socket, init_disk, mac, net_config, hostname, username) {
    print("");
    print("╔════════════════════════════════════════════════════════════╗");
    print("║           Starting Ubuntu VM with Mycelium                 ║");
    print("╚════════════════════════════════════════════════════════════╝");
    print("");

    print("� Initializing VM...");
    let runtime = RuntimeBuilder().api_socket(api_sock);

    if !init_runtime(runtime) {
        print("   ❌ Failed to initialize runtime");
        return;
    }

    let tag = "vroot";
    let cmdline = "console=ttyS0 rootfstype=virtiofs rw net.ifnames=0 biosdevname=0 root=" + tag;
    
    let vm_spec = VMBuilder()
        .kernel(root_dir + "/boot/vmlinuz")
        .initramfs(root_dir + "/boot/initrd.img")
        .cmdline(cmdline)
        .cpus(2)
        .memory(2048)
        .memory_shared(true)
        .virtio_fs(tag, virt_socket)
        .virtio_blk(init_disk, true)
        .virtio_net_with_mac(net_config.tap_device, mac)
        .serial("tty")
        .console("off")
        .build();

    let vm = create_vm(vm_spec);
    start_vm(vm);
    
    // Wait for VM to reach Running state
    let max_wait = 30;
    let elapsed = 0;
    let running = false;
    
    while elapsed < max_wait {
        let status = get_vm_status(vm);
        if status == "Running" {
            running = true;
            break;
        }
        sleep(1000);
        elapsed += 1;
    }
    
    if !running {
        print("   ❌ VM failed to start within " + max_wait + " seconds");
        return;
    }
    print("   ✓ VM started");
    print("");

    print("╔════════════════════════════════════════════════════════════╗");
    print("║                    VM INFORMATION                          ║");
    print("╚════════════════════════════════════════════════════════════╝");
    print("");
    print("  Hostname:      " + hostname);
    print("  Username:      " + username);
    print("  Mycelium IP:   " + net_config.mycelium_ip);
    if net_config.private_ip != () {
        print("  Private IP:    " + net_config.private_ip);
    }
    print("");
    print("  SSH Access:    ssh " + username + "@" + net_config.mycelium_ip.split("/")[0]);
    print("");

    print("⏳ Waiting for cloud-init (30s)...");
    sleep(30000);
    print("   ✓ VM ready");
    print("");
    print("✅ VM is running. Press Ctrl+C to stop.");
    print("");

    loop {
        sleep(60000);
    }
}

unpack_image(flist_path, root_fs_dir);
let net_config = setup_network();
create_config(net_config, vm_mac, hostname, username, ssh_key, hero_init_disk_path);
share_rootfs(root_fs_dir, virtio_socket);
run_vm(api_socket, root_fs_dir, virtio_socket, hero_init_disk_path, vm_mac, net_config, hostname, username);