/*
 * Sample client for the VirtualBox webservice, written in Java.
 *
 * Don't forget to run VBOX webserver 
 * with 'vboxwebsrv -t 1000' command, to calm down watchdog thread. 
 * 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 *
 *  Sun Microsystems, Inc. confidential
 *  All rights reserved
 */
import com.sun.xml.ws.commons.virtualbox.*;
import java.util.*;
import javax.xml.ws.Holder;
import org.virtualbox.*;

public class clienttest
{
    IVirtualBox vbox;
    IWebsessionManager mgr;

    public clienttest()
    {
        vbox = VirtualBox.connect("http://localhost:18083/");
        mgr = new IWebsessionManager(vbox.getRemoteWSPort());
        System.out.println("Initialized connection to VirtualBox version " + vbox.getVersion());
    }


    public void test()
    {
        ISession session = mgr.getSessionObject(vbox);
        UUID id = UUID.fromString("bc8b6219-2775-42c4-f1b2-b48b3c177294");
        vbox.openSession(session, id);
        IMachine mach = session.getMachine();
        IBIOSSettings bios = mach.getBIOSSettings();
        bios.setIOAPICEnabled(true);
        mach.saveSettings();
        mach.releaseRemote();
        session.close();
    }

    public void showVMs()
    {
        try 
        {

            int i = 0;
            for (IMachine m : vbox.getMachines2()) 
            {                
                System.out.println("Machine " + (i++) + ": " + " ["+m.getId()+"]" + " - " + m.getName());
                m.releaseRemote();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void listHostInfo()
    {
        try
            {
                IHost host = vbox.getHost();
                long uProcCount = host.getProcessorCount();
                System.out.println("Processor count: " + uProcCount);
                
                for (long i=0; i<uProcCount; i++) 
                    {
                         System.out.println("Processor #"+i+" speed: "+
                                            host.getProcessorSpeed(i)+"MHz");
                    }
                
                IPerformanceCollector  oCollector = vbox.getPerformanceCollector();

                List<IPerformanceMetric> aMetrics = 
                    oCollector.getMetrics(Arrays.asList(new String[]{"*"}),
                                          Arrays.asList(new IUnknown[]{host}));
                
                for (IPerformanceMetric m : aMetrics) 
                {
                    System.out.println("known metric = "+m.getMetricName());
                }

                Holder<List<String>> names = new Holder<List<String>> ();
                Holder<List<IUnknown>> objs = new Holder<List<IUnknown>>() ;
                Holder<List<Long>> inds =  new Holder<List<Long>>();
                Holder<List<Long>> lens =  new Holder<List<Long>>();

                List<Integer> vals = 
                    oCollector.queryMetricsData(Arrays.asList(new String[]{"*"}),
                                                Arrays.asList(new IUnknown[]{host}),
                                                names, objs, inds, lens);
                                                     
                for (int i=0; i<vals.size(); i++) {
                    System.out.println("for name: "+names.value.get(i)+
                                       " val="+vals.get(i));                    
                }
                oCollector.releaseRemote();
                host.releaseRemote();
            }
        catch (Exception e)
            {
                e.printStackTrace();
            }
    }

    public void startVM(String strVM)
    {
        ISession oSession = null;
        IMachine oMachine = null;

        try
            {
                oSession = mgr.getSessionObject(vbox);

                // first assume we were given a UUID
                try
                {
                    oMachine = vbox.getMachine(UUID.fromString(strVM));
                } 
                catch (Exception e)
                {
                    try
                    {
                        oMachine = vbox.findMachine(strVM);
                    }
                    catch (Exception e1)
                        {
                        }
                }

                if (oMachine == null)
                    {
                        System.out.println("Error: can't find VM \"" + strVM + "\"");
                    }
                else
                    {
                        UUID uuid = oMachine.getId();
                        String sessionType = "gui";
                        String env = "DISPLAY=:0.0";
                        IProgress oProgress = 
                            vbox.openRemoteSession(oSession, 
                                                   uuid, 
                                                   sessionType,
                                                   env);
                        System.out.println("Session for VM " + uuid + " is opening...");
                        oProgress.waitForCompletion(10000);

                        long rc = oProgress.getResultCode();
                        if (rc != 0)
                            {
                                System.out.println("Session failed!");
                            }                        
                    }
            }
        catch (Exception e)
            {
                e.printStackTrace();
            }
        finally 
            {
                if (oMachine != null) 
                    {
                        oMachine.releaseRemote();
                    }
                 if (oSession != null) 
                    {
                        oSession.close();
                    }
            }
    }

    public void cleanup()
    {
        try
            {
                if (vbox != null)
                    {
                        mgr.logoff(vbox);
                        vbox = null;
                        mgr = null;
                        System.out.println("Logged off.");
                    }
            }
        catch (Exception e)
            {
                e.printStackTrace();
            }
    }
    
    public static void printArgs()
    {
        System.out.println(  "Usage: java clienttest <mode> ..." +
                             "\nwith <mode> being:" +
                             "\n   show vms            list installed virtual machines" +
                             "\n   list hostinfo       list host info" +
                             "\n   startvm <vmname|uuid> start the given virtual machine");
    }

    public static void main(String[] args)
    {
        if (args.length < 1)
            {
                System.out.println("Error: Must specify at least one argument.");
                printArgs();
            }
        else
            {
                clienttest c = new clienttest();
                if (args[0].equals("show"))
                    {
                        if (args.length == 2)
                            {
                                if (args[1].equals("vms"))
                                    c.showVMs();
                                else
                                    System.out.println("Error: Unknown argument to \"show\": \"" + args[1] + "\".");
                            }
                        else
                            System.out.println("Error: Missing argument to \"show\" command");
                    }
                else if (args[0].equals("list"))
                    {
                        if (args.length == 2)
                            {
                                if (args[1].equals("hostinfo"))
                                    c.listHostInfo();
                                else
                                    System.out.println("Error: Unknown argument to \"show\": \"" + args[1] + "\".");
                            }
                        else
                            System.out.println("Error: Missing argument to \"show\" command");
                    }
                else if (args[0].equals("startvm"))
                    {
                        if (args.length == 2)
                            {
                                c.startVM(args[1]);
                            }
                        else
                            System.out.println("Error: Missing argument to \"startvm\" command");
                    }
                else if (args[0].equals("test"))
                    {
                        c.test();
                    }
                else
                    System.out.println("Error: Unknown command: \"" + args[0] + "\".");

                c.cleanup();
            }
    }
}
