﻿// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using log4net;
using Microsoft.CSharp.RuntimeBinder;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Web.Http;
using CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2;

namespace HypervResource
{

    public struct HypervResourceControllerConfig
    {
        private string privateIpAddress;
        private static ILog logger = LogManager.GetLogger(typeof(HypervResourceControllerConfig));

        public string PrivateIpAddress
        {
            get
            {
                return privateIpAddress;
            }
            set
            {
                ValidateIpAddress(value);
                privateIpAddress = value;
                System.Net.NetworkInformation.NetworkInterface nic = HypervResourceController.GetNicInfoFromIpAddress(privateIpAddress, out PrivateNetmask);
                PrivateMacAddress = nic.GetPhysicalAddress().ToString();
            }
        }

        private static void ValidateIpAddress(string value)
        {
            // Convert to IP address
            IPAddress ipAddress;
            if (!IPAddress.TryParse(value, out ipAddress))
            {
                String errMsg = "Invalid PrivateIpAddress: " + value;
                logger.Error(errMsg);
                throw new ArgumentException(errMsg);
            }
        }
        public string GatewayIpAddress;
        public string PrivateMacAddress;
        public string PrivateNetmask;
        public string StorageNetmask;
        public string StorageMacAddress;
        public string StorageIpAddress;
        public long RootDeviceReservedSpaceBytes;
        public string RootDeviceName;
        public ulong ParentPartitionMinMemoryMb;
        public string LocalSecondaryStoragePath;
        public string systemVmIso;

        private string getPrimaryKey(string id)
        {
            return "primary_storage_" + id;
        }

        public string getPrimaryStorage(string id)
        {
            NameValueCollection settings = ConfigurationManager.AppSettings;
            return settings.Get(getPrimaryKey(id));
        }

        public void setPrimaryStorage(string id, string path)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            KeyValueConfigurationCollection settings = config.AppSettings.Settings;
            string key = getPrimaryKey(id);
            if (settings[key] != null)
            {
                settings.Remove(key);
            }
            settings.Add(key, path);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
    }

    /// <summary>
    /// Supports one HTTP GET and multiple HTTP POST URIs
    /// </summary>
    /// <remarks>
    /// <para>
    /// POST takes dynamic to allow it to receive JSON without concern for what is the underlying object.
    /// E.g. http://stackoverflow.com/questions/14071715/passing-dynamic-json-object-to-web-api-newtonsoft-example 
    /// and http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object
    /// Use ActionName attribute to allow multiple POST URLs, one for each supported command
    /// E.g. http://stackoverflow.com/a/12703423/939250
    /// Strictly speaking, this goes against the purpose of an ApiController, which is to provide one GET/POST/PUT/DELETE, etc.
    /// However, it reduces the amount of code by removing the need for a switch according to the incoming command type.
    /// http://weblogs.asp.net/fredriknormen/archive/2012/06/11/asp-net-web-api-exception-handling.aspx
    /// </para>
    /// <para>
    /// Exceptions handled on command by command basis rather than globally to allow details of the command
    /// to be reflected in the response.  Default error handling is in the catch for Exception, but
    /// other exception types may be caught where the feedback would be different.
    /// NB: global alternatives discussed at 
    /// http://weblogs.asp.net/fredriknormen/archive/2012/06/11/asp-net-web-api-exception-handling.aspx
    /// </para>
    /// </remarks>
    public class HypervResourceController : ApiController
    {
        public static void Configure(HypervResourceControllerConfig config)
        {
            HypervResourceController.config = config;
            wmiCallsV2 = new WmiCallsV2();
        }

        public static HypervResourceControllerConfig config = new HypervResourceControllerConfig();

        private static ILog logger = LogManager.GetLogger(typeof(HypervResourceController));
        private string systemVmIso  = "";
        Dictionary<String, String> contextMap = new Dictionary<String, String>();

        public static void Initialize()
        {
        }

        public static IWmiCallsV2 wmiCallsV2 { get; set;}

        // GET api/HypervResource
        public string Get()
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                return "HypervResource controller running, use POST to send JSON encoded RPCs"; ;
            }
        }

        /// <summary>
        /// NOP - placeholder for future setup, e.g. delete existing VMs or Network ports 
        /// POST api/HypervResource/SetupCommand
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        /// TODO: produce test
        [HttpPost]
        [ActionName(CloudStackTypes.SetupCommand)]
        public JContainer SetupCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.SetupCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    result = true;
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.SetupCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = "success - NOP",
                    _reconnect = false,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.SetupAnswer);
            }
        }

        // POST api/HypervResource/AttachCommand
        [HttpPost]
        [ActionName(CloudStackTypes.AttachCommand)]
        public JContainer AttachCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.AttachCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    string vmName = (string)cmd.vmName;
                    DiskTO disk = DiskTO.ParseJson(cmd.disk);

                    if (disk.type.Equals("ISO"))
                    {
                        TemplateObjectTO dataStore = disk.templateObjectTO;
                        NFSTO share = dataStore.nfsDataStoreTO;
                        Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
                        string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
                        wmiCallsV2.AttachIso(vmName, diskPath);
                        result = true;
                    }
                    else if (disk.type.Equals("DATADISK"))
                    {
                        VolumeObjectTO volume = disk.volumeObjectTO;
                        PrimaryDataStoreTO primary = volume.primaryDataStore;
                        if (!primary.isLocal)
                        {
                            Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password);
                        }
                        string diskPath = Utils.NormalizePath(volume.FullFileName);
                        wmiCallsV2.AttachDisk(vmName, diskPath, disk.diskSequence);
                        result = true;
                    }
                    else
                    {
                        details = "Invalid disk type to be attached to vm " + vmName;
                    }
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.AttachCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    disk = cmd.disk,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.AttachAnswer);
            }
        }

        // POST api/HypervResource/DetachCommand
        [HttpPost]
        [ActionName(CloudStackTypes.DettachCommand)]
        public JContainer DetachCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.DettachCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    string vmName = (string)cmd.vmName;
                    DiskTO disk = DiskTO.ParseJson(cmd.disk);

                    if (disk.type.Equals("ISO"))
                    {
                        TemplateObjectTO dataStore = disk.templateObjectTO;
                        NFSTO share = dataStore.nfsDataStoreTO;
                        string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
                        wmiCallsV2.DetachDisk(vmName, diskPath);
                        result = true;
                    }
                    else if (disk.type.Equals("DATADISK"))
                    {
                        VolumeObjectTO volume = disk.volumeObjectTO;
                        PrimaryDataStoreTO primary = volume.primaryDataStore;
                        string diskPath = Utils.NormalizePath(volume.FullFileName);
                        wmiCallsV2.DetachDisk(vmName, diskPath);
                        result = true;
                    }
                    else
                    {
                        details = "Invalid disk type to be dettached from vm " + vmName;
                    }
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.DettachCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.DettachAnswer);
            }
        }

        // POST api/HypervResource/RebootCommand
        [HttpPost]
        [ActionName(CloudStackTypes.RebootCommand)]
        public JContainer RebootCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.RebootCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    string vmName = (string)cmd.vmName;
                    var sys = wmiCallsV2.GetComputerSystem(vmName);
                    if (sys == null)
                    {
                        details = CloudStackTypes.RebootCommand + " requested unknown VM " + vmName;
                        logger.Error(details);
                    }
                    else
                    {
                        wmiCallsV2.SetState(sys, RequiredState.Reset);
                        result = true;
                    }
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.RebootCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.RebootAnswer);
            }
        }

        // POST api/HypervResource/DestroyCommand
        [HttpPost]
        [ActionName(CloudStackTypes.DestroyCommand)]
        public JContainer DestroyCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.DestroyCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    // Assert
                    String errMsg = "No 'volume' details in " + CloudStackTypes.DestroyCommand + " " + cmd.ToString();
                    if (cmd.volume == null)
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }

                    // Assert
                    errMsg = "No valide path in DestroyCommand in " + CloudStackTypes.DestroyCommand + " " + (String)cmd.ToString();
                    if (cmd.volume.path == null)
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }

                    String path = (string)cmd.volume.path;
                    if (!File.Exists(path))
                    {
                        logger.Info(CloudStackTypes.DestroyCommand + ", but volume at pass already deleted " + path);
                    }

                    string vmName = (string)cmd.vmName;
                    if (!string.IsNullOrEmpty(vmName) && File.Exists(path))
                    {
                        // Make sure that this resource is removed from the VM
                        wmiCallsV2.DetachDisk(vmName, path);
                    }

                    File.Delete(path);
                    result = true;
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.DestroyCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                    {
                        result = result,
                        details = details,
                        contextMap = contextMap
                    };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        // POST api/HypervResource/DeleteCommand
        [HttpPost]
        [ActionName(CloudStackTypes.DeleteCommand)]
        public JContainer DeleteCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.DestroyCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    // Assert
                    String errMsg = "No 'volume' details in " + CloudStackTypes.DestroyCommand + " " + cmd.ToString();
                    VolumeObjectTO destVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.data);

                    if (destVolumeObjectTO.name == null)
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }

                    String path = destVolumeObjectTO.FullFileName;
                    if (!File.Exists(path))
                    {
                        logger.Info(CloudStackTypes.DestroyCommand + ", but volume at pass already deleted " + path);
                    }

                    string vmName = (string)cmd.vmName;
                    if (!string.IsNullOrEmpty(vmName) && File.Exists(path))
                    {
                        // Make sure that this resource is removed from the VM
                        wmiCallsV2.DetachDisk(vmName, path);
                    }

                    File.Delete(path);
                    result = true;
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.DestroyCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        
        private static JArray ReturnCloudStackTypedJArray(object ansContent, string ansType)
        {
            JObject ansObj = Utils.CreateCloudStackObject(ansType, ansContent);
            JArray answer = new JArray(ansObj);
            logger.Info(ansObj.ToString());
            return answer;
        }

        // POST api/HypervResource/CreateCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CreateCommand)]
        public JContainer CreateCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CreateCommand + cmd.ToString());

                string details = null;
                bool result = false;
                VolumeInfo volume = new VolumeInfo();

                try
                {
                    string diskType = cmd.diskCharacteristics.type;
                    ulong disksize = cmd.diskCharacteristics.size;
                    string templateUri = cmd.templateUrl;

                    // assert: valid storagepool?
                    string poolTypeStr = cmd.pool.type;
                    string poolLocalPath = cmd.pool.path;
                    string poolUuid = cmd.pool.uuid;
                    string newVolPath = null;
                    long volId = cmd.volId;
                    string newVolName = null;

                    if (ValidStoragePool(poolTypeStr, poolLocalPath, poolUuid, ref details))
                    {
                        // No template URI?  Its a blank disk.
                        if (string.IsNullOrEmpty(templateUri))
                        {
                            // assert
                            VolumeType volType;
                            if (!Enum.TryParse<VolumeType>(diskType, out volType) && volType != VolumeType.DATADISK)
                            {
                                details = "Cannot create volumes of type " + (string.IsNullOrEmpty(diskType) ? "NULL" : diskType);
                            }
                            else
                            {
                                newVolName = cmd.diskCharacteristics.name;
                                newVolPath = Path.Combine(poolLocalPath, newVolName, diskType.ToLower());
                                // TODO: make volume format and block size configurable
                                wmiCallsV2.CreateDynamicVirtualHardDisk(disksize, newVolPath);
                                if (File.Exists(newVolPath))
                                {
                                    result = true;
                                }
                                else
                                {
                                    details = "Failed to create DATADISK with name " + newVolName;
                                }
                            }
                        }
                        else
                        {
                            // TODO:  Does this always work, or do I need to download template at times?
                            if (templateUri.Contains("/") || templateUri.Contains("\\"))
                            {
                                details = "Problem with templateURL " + templateUri +
                                                " the URL should be volume UUID in primary storage created by previous PrimaryStorageDownloadCommand";
                                logger.Error(details);
                            }
                            else
                            {
                                logger.Debug("Template's name in primary store should be " + templateUri);
                                //            HypervPhysicalDisk BaseVol = primaryPool.getPhysicalDisk(tmplturl);
                                FileInfo srcFileInfo = new FileInfo(templateUri);
                                newVolName = Guid.NewGuid() + srcFileInfo.Extension;
                                newVolPath = Path.Combine(poolLocalPath, newVolName);
                                logger.Debug("New volume will be at " + newVolPath);
                                string oldVolPath = Path.Combine(poolLocalPath, templateUri);
                                File.Copy(oldVolPath, newVolPath);
                                if (File.Exists(newVolPath))
                                {
                                    result = true;
                                }
                                else
                                {
                                    details = "Failed to create DATADISK with name " + newVolName;
                                }
                            }
                            volume = new VolumeInfo(
                                      volId, diskType,
                                    poolTypeStr, poolUuid, newVolName,
                                    newVolPath, newVolPath, (long)disksize, null);
                        }
                    }
                }
                catch (Exception sysEx)
                {
                    // TODO: consider this as model for error processing in all commands
                    details = CloudStackTypes.CreateCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    volume = volume,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateAnswer);
            }
        }

        // POST api/HypervResource/PrimaryStorageDownloadCommand
        [HttpPost]
        [ActionName(CloudStackTypes.PrimaryStorageDownloadCommand)]
        public JContainer PrimaryStorageDownloadCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + cmd.ToString());
                string details = null;
                bool result = false;
                long size = 0;
                string newCopyFileName = null;

                string poolLocalPath = cmd.localPath;
                string poolUuid = cmd.poolUuid;
                if (!Directory.Exists(poolLocalPath))
                {
                    details = "None existent local path " + poolLocalPath;
                }
                else
                {
                    // Compose name for downloaded file.
                    string sourceUrl = cmd.url;
                    if (sourceUrl.ToLower().EndsWith(".vhd"))
                    {
                        newCopyFileName = Guid.NewGuid() + ".vhd";
                    }
                    if (sourceUrl.ToLower().EndsWith(".vhdx"))
                    {
                        newCopyFileName = Guid.NewGuid() + ".vhdx";
                    }

                    // assert
                    if (newCopyFileName == null)
                    {
                        details = CloudStackTypes.PrimaryStorageDownloadCommand + " Invalid file extension for hypervisor type in source URL " + sourceUrl;
                        logger.Error(details);
                    }
                    else
                    {
                        try
                        {
                            FileInfo newFile;
                            if (CopyURI(sourceUrl, newCopyFileName, poolLocalPath, out newFile, ref details))
                            {
                                size = newFile.Length;
                                result = true;
                            }
                        }
                        catch (System.Exception ex)
                        {
                            details = CloudStackTypes.PrimaryStorageDownloadCommand + " Cannot download source URL " + sourceUrl + " due to " + ex.Message;
                            logger.Error(details, ex);
                        }
                    }
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    templateSize = size,
                    installPath = newCopyFileName,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PrimaryStorageDownloadAnswer);
            }
        }

        private static bool ValidStoragePool(string poolTypeStr, string poolLocalPath, string poolUuid, ref string details)
        {
            StoragePoolType poolType;
            if (!Enum.TryParse<StoragePoolType>(poolTypeStr, out poolType) || poolType != StoragePoolType.Filesystem)
            {
                details = "Primary storage pool " + poolUuid + " type " + poolType + " local path " + poolLocalPath + " has invalid StoragePoolType";
                logger.Error(details);
                return false;
            }
            else if (!Directory.Exists(poolLocalPath))
            {
                details = "Primary storage pool " + poolUuid + " type " + poolType + " local path " + poolLocalPath + " has invalid local path";
                logger.Error(details);
                return false;
            }
            return true;
        }

        /// <summary>
        /// Exceptions to watch out for:
        /// Exceptions related to URI creation
        /// System.SystemException
        /// +-System.ArgumentNullException
        /// +-System.FormatException
        ///   +-System.UriFormatException
        ///
        /// Exceptions related to NFS URIs
        /// System.SystemException
        /// +-System.NotSupportedException
        /// +-System.ArgumentException
        /// +-System.ArgumentNullException
        ///   +-System.Security.SecurityException;
        /// +-System.UnauthorizedAccessException
        /// +-System.IO.IOException
        ///   +-System.IO.PathTooLongException
        ///   
        /// Exceptions related to HTTP URIs
        /// System.SystemException
        /// +-System.InvalidOperationException
        ///    +-System.Net.WebException
        /// +-System.NotSupportedException
        /// +-System.ArgumentNullException
        /// </summary>
        /// <param name="sourceUri"></param>
        /// <param name="newCopyFileName"></param>
        /// <param name="poolLocalPath"></param>
        /// <returns></returns>
        private bool CopyURI(string sourceUri, string newCopyFileName, string poolLocalPath, out FileInfo newFile, ref string details)
        {
            Uri source = new Uri(sourceUri);
            String destFilePath = Path.Combine(poolLocalPath, newCopyFileName);
            string[] pathSegments = source.Segments;
            String templateUUIDandExtension = pathSegments[pathSegments.Length - 1];
            newFile = new FileInfo(destFilePath);

            // NFS URI assumed to already be mounted locally.  Mount location given by settings.
            if (source.Scheme.ToLower().Equals("nfs"))
            {
                String srcDiskPath = Path.Combine(HypervResourceController.config.LocalSecondaryStoragePath, templateUUIDandExtension);
                String taskMsg = "Copy NFS url in " + sourceUri + " at " + srcDiskPath + " to pool " + poolLocalPath;
                logger.Debug(taskMsg);
                File.Copy(srcDiskPath, destFilePath);
            }
            else if (source.Scheme.ToLower().Equals("http") || source.Scheme.ToLower().Equals("https"))
            {
                System.Net.WebClient webclient = new WebClient();
                webclient.DownloadFile(source, destFilePath);
            }
            else
            {
                details = "Unsupported URI scheme " + source.Scheme.ToLower() + " in source URI " + sourceUri;
                logger.Error(details);
                return false;
            }

            if (!File.Exists(destFilePath))
            {
                details = "Filed to copy " + sourceUri + " to primary pool destination " + destFilePath;
                logger.Error(details);
                return false;
            }
            return true;
        }

        // POST api/HypervResource/CheckHealthCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CheckHealthCommand)]
        public JContainer CheckHealthCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CheckHealthCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = "resource is alive",
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckHealthAnswer);
            }
        }

        // POST api/HypervResource/CheckOnHostCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CheckOnHostCommand)]
        public JContainer CheckOnHostCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CheckOnHostCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = "resource is alive",
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckOnHostAnswer);
            }
        }

        // POST api/HypervResource/CheckSshCommand
        // TODO: create test
        [HttpPost]
        [ActionName(CloudStackTypes.CheckSshCommand)]
        public JContainer CheckSshCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CheckSshCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = "NOP, TODO: implement properly",
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckSshAnswer);
            }
        }

        // POST api/HypervResource/CheckVirtualMachineCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CheckVirtualMachineCommand)]
        public JContainer CheckVirtualMachineCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CheckVirtualMachineCommand + cmd.ToString());
                string details = null;
                bool result = false;
                string vmName = cmd.vmName;
                string state = null;

                // TODO: Look up the VM, convert Hyper-V state to CloudStack version.
                var sys = wmiCallsV2.GetComputerSystem(vmName);
                if (sys == null)
                {
                    details = CloudStackTypes.CheckVirtualMachineCommand + " requested unknown VM " + vmName;
                    logger.Error(details);
                }
                else
                {
                    state = EnabledState.ToCloudStackState(sys.EnabledState); // TODO: V2 changes?
                    result = true;
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    state = state,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckVirtualMachineAnswer);
            }
        }

        // POST api/HypervResource/DeleteStoragePoolCommand
        [HttpPost]
        [ActionName(CloudStackTypes.DeleteStoragePoolCommand)]
        public JContainer DeleteStoragePoolCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.DeleteStoragePoolCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = "Current implementation does not delete local path corresponding to storage pool!",
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        /// <summary>
        /// NOP - legacy command -
        /// POST api/HypervResource/CreateStoragePoolCommand
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName(CloudStackTypes.CreateStoragePoolCommand)]
        public JContainer CreateStoragePoolCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CreateStoragePoolCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = "success - NOP",
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        // POST api/HypervResource/ModifyStoragePoolCommand
        [HttpPost]
        [ActionName(CloudStackTypes.ModifyStoragePoolCommand)]
        public JContainer ModifyStoragePoolCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.ModifyStoragePoolCommand + cmd.ToString());
                string details = null;
                string localPath;
                StoragePoolType poolType;
                object ansContent;

                bool result = ValidateStoragePoolCommand(cmd, out localPath, out poolType, ref details);
                if (!result)
                {
                    ansContent = new
                    {
                        result = result,
                        details = details,
                        contextMap = contextMap
                    };
                    return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
                }

                var tInfo = new Dictionary<string, string>();
                long capacityBytes = 0;
                long availableBytes = 0;
                string hostPath = null;
                if (poolType == StoragePoolType.Filesystem)
                {
                    GetCapacityForLocalPath(localPath, out capacityBytes, out availableBytes);
                    hostPath = localPath;
                }
                else if (poolType == StoragePoolType.NetworkFilesystem)
                {
                    NFSTO share = new NFSTO();
                    String uriStr = "cifs://" + (string)cmd.pool.host + (string)cmd.pool.path;
                    share.uri = new Uri(uriStr);
                    hostPath = Utils.NormalizePath(share.UncPath);

                    // Check access to share.
                    Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
                    Utils.GetShareDetails(share.UncPath, out capacityBytes, out availableBytes);
                    config.setPrimaryStorage((string)cmd.pool.uuid, hostPath);
                }
                else
                {
                    result = false;
                }

                String uuid = null;
                var poolInfo = new
                {
                    uuid = uuid,
                    host = cmd.pool.host,
                    hostPath = cmd.pool.path,
                    localPath = hostPath,
                    poolType = cmd.pool.type,
                    capacityBytes = capacityBytes,
                    availableBytes = availableBytes
                };

                ansContent = new
                {
                    result = result,
                    details = details,
                    localPath = hostPath,
                    templateInfo = tInfo,
                    poolInfo = poolInfo,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyStoragePoolAnswer);
            }
        }

        private bool ValidateStoragePoolCommand(dynamic cmd, out string localPath, out StoragePoolType poolType, ref string details)
        {
            dynamic pool = cmd.pool;
            string poolTypeStr = pool.type;
            localPath = cmd.localPath;
            if (!Enum.TryParse<StoragePoolType>(poolTypeStr, out poolType))
            {
                details = "Request to create / modify unsupported pool type: " + (poolTypeStr == null ? "NULL" : poolTypeStr) + "in cmd " + JsonConvert.SerializeObject(cmd);
                logger.Error(details);
                return false;
            }

            if (poolType != StoragePoolType.Filesystem &&
                poolType != StoragePoolType.NetworkFilesystem)
            {
                details = "Request to create / modify unsupported pool type: " + (poolTypeStr == null ? "NULL" : poolTypeStr) + "in cmd " + JsonConvert.SerializeObject(cmd);
                logger.Error(details);
                return false;
            }

            return true;
        }


        // POST api/HypervResource/CleanupNetworkRulesCmd
        [HttpPost]
        [ActionName(CloudStackTypes.CleanupNetworkRulesCmd)]
        public JContainer CleanupNetworkRulesCmd([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CleanupNetworkRulesCmd + cmd.ToString());
                object ansContent = new
                 {
                     result = false,
                     details = "nothing to cleanup in our current implementation",
                     contextMap = contextMap
                 };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        // POST api/HypervResource/CheckNetworkCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CheckNetworkCommand)]
        public JContainer CheckNetworkCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CheckNetworkCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = (string)null,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CheckNetworkAnswer);
            }
        }

        // POST api/HypervResource/ReadyCommand
        [HttpPost]
        [ActionName(CloudStackTypes.ReadyCommand)]
        public JContainer ReadyCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.ReadyCommand + cmd.ToString());
                object ansContent = new
                {
                    result = true,
                    details = (string)null,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ReadyAnswer);
            }

        }

        // POST api/HypervResource/StartCommand
        [HttpPost]
        [ActionName(CloudStackTypes.StartCommand)]
        public JContainer StartCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.StartCommand + cmd.ToString()); // TODO: Security hole? VM data printed to log
                string details = null;
                bool result = false;

                try
                {
                    string systemVmIsoPath = systemVmIso;
                    lock (systemVmIso)
                    {
                        systemVmIsoPath = systemVmIso;
                        String uriStr = (String)cmd.secondaryStorage;
                        if (!String.IsNullOrEmpty(uriStr))
                        {
                            if (String.IsNullOrEmpty(systemVmIsoPath) || !File.Exists(systemVmIsoPath))
                            {
                                NFSTO share = new NFSTO();
                                share.uri = new Uri(uriStr);
                                string defaultDataPath = wmiCallsV2.GetDefaultDataRoot();

                                string secondaryPath = Utils.NormalizePath(Path.Combine(share.UncPath, "systemvm"));
                                string[] choices = choices = Directory.GetFiles(secondaryPath, "systemvm*.iso");
                                if (choices.Length != 1)
                                {
                                    String errMsg = "Couldn't locate the systemvm iso on " + secondaryPath;
                                    logger.Debug(errMsg);
                                }
                                else
                                {
                                    systemVmIsoPath = Utils.NormalizePath(Path.Combine(defaultDataPath, Path.GetFileName(choices[0])));
                                    if (!File.Exists(systemVmIsoPath))
                                    {
                                        Utils.DownloadCifsFileToLocalFile(choices[0], share, systemVmIsoPath);
                                    }
                                    systemVmIso = systemVmIsoPath;
                                }
                            }
                        }
                    }

                    wmiCallsV2.DeployVirtualMachine(cmd, systemVmIsoPath);
                    result = true;
                }
                catch (Exception wmiEx)
                {
                    details = CloudStackTypes.StartCommand + " fail on exception" + wmiEx.Message;
                    logger.Error(details, wmiEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    vm = cmd.vm,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.StartAnswer);
            }
        }

        // POST api/HypervResource/StopCommand
        [HttpPost]
        [ActionName(CloudStackTypes.StopCommand)]
        public JContainer StopCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.StopCommand + cmd.ToString());
                string details = null;
                bool result = false;

                try
                {
                    wmiCallsV2.DestroyVm(cmd);
                    result = true;
                }
                catch (Exception wmiEx)
                {
                    details = CloudStackTypes.StopCommand + " fail on exception" + wmiEx.Message;
                    logger.Error(details, wmiEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    vm = cmd.vm,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.StopAnswer);
            }
        }

        // POST api/HypervResource/CreateObjectCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CreateObjectCommand)]
        public JContainer CreateObjectCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.CreateObjectCommand + cmd.ToString());

                bool result = false;
                string details = null;

                try
                {
                    VolumeObjectTO volume = VolumeObjectTO.ParseJson(cmd.data);
                    PrimaryDataStoreTO primary = volume.primaryDataStore;
                    ulong volumeSize = volume.size;
                    string volumeName = volume.name + ".vhd";
                    string volumePath = null;

                    if (primary.isLocal)
                    {
                        volumePath = Path.Combine(primary.Path, volumeName);
                    }
                    else
                    {
                        volumePath = @"\\" + primary.uri.Host + primary.uri.LocalPath + @"\" + volumeName;
                        volumePath = Utils.NormalizePath(volumePath);
                        Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password);
                    }

                    wmiCallsV2.CreateDynamicVirtualHardDisk(volumeSize, volumePath);
                    if (File.Exists(volumePath))
                    {
                        result = true;
                    }
                    else
                    {
                        details = "Failed to create disk with name " + volumePath;
                    }
                }
                catch (Exception ex)
                {
                    // Test by providing wrong key
                    details = CloudStackTypes.CreateObjectCommand + " failed on exception, " + ex.Message;
                    logger.Error(details, ex);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    data = cmd.data,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CreateObjectAnswer);
            }
        }

        // POST api/HypervResource/MaintainCommand
        // TODO: should this be a NOP?
        [HttpPost]
        [ActionName(CloudStackTypes.MaintainCommand)]
        public JContainer MaintainCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.MaintainCommand + cmd.ToString());

                object ansContent = new
                {
                    result = true,
                    willMigrate = true,
                    details = "success - NOP for MaintainCommand",
                    _reconnect = false,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.MaintainAnswer);
            }
        }

        // POST api/HypervResource/PingRoutingCommand
        // TODO: should this be a NOP?
        [HttpPost]
        [ActionName(CloudStackTypes.PingRoutingCommand)]
        public JContainer PingRoutingCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.PingRoutingCommand + cmd.ToString());

                object ansContent = new
                {
                    result = true,
                    details = "success - NOP for PingRoutingCommand",
                    _reconnect = false,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        // POST api/HypervResource/PingCommand
        // TODO: should this be a NOP?
        [HttpPost]
        [ActionName(CloudStackTypes.PingCommand)]
        public JContainer PingCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.PingCommand + cmd.ToString());

                object ansContent = new
                {
                    result = true,
                    details = "success - NOP for PingCommand",
                    _reconnect = false,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.Answer);
            }
        }

        // POST api/HypervResource/GetVmStatsCommand
        [HttpPost]
        [ActionName(CloudStackTypes.GetVmStatsCommand)]
        public JContainer GetVmStatsCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.GetVmStatsCommand + cmd.ToString());
                bool result = false;
                JArray vmNamesJson = cmd.vmNames;
                string[] vmNames = vmNamesJson.ToObject<string[]>();
                Dictionary<string, VmStatsEntry> vmProcessorInfo = new Dictionary<string, VmStatsEntry>(vmNames.Length);

                var vmsToInspect = new List<System.Management.ManagementPath>();
                foreach (var vmName in vmNames)
                {
                    var sys = wmiCallsV2.GetComputerSystem(vmName);
                    if (sys == null)
                    {
                        logger.InfoFormat("GetVmStatsCommand requested unknown VM {0}", vmNames);
                        continue;
                    }
                    var sysInfo = wmiCallsV2.GetVmSettings(sys);
                    vmsToInspect.Add(sysInfo.Path);
                }

                wmiCallsV2.GetSummaryInfo(vmProcessorInfo, vmsToInspect);

                // TODO: Network usage comes from Performance Counter API; however it is only available in kb/s, and not in total terms.
                // Curious about these?  Use perfmon to inspect them, e.g. http://msdn.microsoft.com/en-us/library/xhcx5a20%28v=vs.100%29.aspx
                // Recent post on these counter at http://blogs.technet.com/b/cedward/archive/2011/07/19/hyper-v-networking-optimizations-part-6-of-6-monitoring-hyper-v-network-consumption.aspx
                result = true;

                object ansContent = new
                {
                    vmStatsMap = vmProcessorInfo,
                    result = result,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmStatsAnswer);
            }
        }

        // POST api/HypervResource/CopyCommand
        [HttpPost]
        [ActionName(CloudStackTypes.CopyCommand)]
        public JContainer CopyCommand(dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                // Log command *after* we've removed security details from the command.
                logger.Info(CloudStackTypes.CopyCommand + cmd.ToString());

                bool result = false;
                string details = null;
                object newData = null;
                TemplateObjectTO destTemplateObjectTO = null;
                VolumeObjectTO destVolumeObjectTO = null;
                VolumeObjectTO srcVolumeObjectTO = null;
                TemplateObjectTO srcTemplateObjectTO = null;

                try
                {
                    dynamic timeout = cmd.wait;  // TODO: Useful?

                    srcTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.srcTO);
                    destTemplateObjectTO = TemplateObjectTO.ParseJson(cmd.destTO);
                    srcVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.srcTO);
                    destVolumeObjectTO = VolumeObjectTO.ParseJson(cmd.destTO);

                    string destFile = null;
                    if (destTemplateObjectTO != null)
                    {
                        if (destTemplateObjectTO.primaryDataStore != null)
                        {
                            destFile = destTemplateObjectTO.FullFileName;
                            if (!destTemplateObjectTO.primaryDataStore.isLocal)
                            {
                                PrimaryDataStoreTO primary = destTemplateObjectTO.primaryDataStore;
                                Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password);
                            }
                        }
                        else if (destTemplateObjectTO.nfsDataStoreTO != null)
                        {
                            destFile = destTemplateObjectTO.FullFileName;
                            NFSTO store = destTemplateObjectTO.nfsDataStoreTO;
                            Utils.ConnectToRemote(store.UncPath, store.Domain, store.User, store.Password);
                        }
                    }

                    // Template already downloaded?
                    if (destFile != null && File.Exists(destFile) &&
                        !String.IsNullOrEmpty(destTemplateObjectTO.checksum))
                    {
                        // TODO: checksum fails us, because it is of the compressed image.
                        // ASK: should we store the compressed or uncompressed version or is the checksum not calculated correctly?
                        logger.Debug(CloudStackTypes.CopyCommand + " calling VerifyChecksum to see if we already have the file at " + destFile);
                        result = VerifyChecksum(destFile, destTemplateObjectTO.checksum);
                        if (!result)
                        {
                            result = true;
                            logger.Debug(CloudStackTypes.CopyCommand + " existing file has different checksum " + destFile);
                        }
                    }

                    // Do we have to create a new one?
                    if (!result)
                    {
                        // Create local copy of a template?
                        if (srcTemplateObjectTO != null && destTemplateObjectTO != null)
                        {
                            // S3 download to primary storage?
                            // NFS provider download to primary storage?
                            if ((srcTemplateObjectTO.s3DataStoreTO != null || srcTemplateObjectTO.nfsDataStoreTO != null) && destTemplateObjectTO.primaryDataStore != null)
                            {
                                if (File.Exists(destFile))
                                {
                                    logger.Info("Deleting existing file " + destFile);
                                    File.Delete(destFile);
                                }

                                if (srcTemplateObjectTO.s3DataStoreTO != null)
                                {
                                    // Download from S3 to destination data storage
                                    DownloadS3ObjectToFile(srcTemplateObjectTO.path, srcTemplateObjectTO.s3DataStoreTO, destFile);
                                }
                                else if (srcTemplateObjectTO.nfsDataStoreTO != null)
                                {
                                    // Download from S3 to destination data storage
                                    Utils.DownloadCifsFileToLocalFile(srcTemplateObjectTO.path, srcTemplateObjectTO.nfsDataStoreTO, destFile);
                                }

                                // Uncompress, as required
                                if (srcTemplateObjectTO.path.EndsWith(".bz2"))
                                {
                                    String uncompressedFile = destFile + ".tmp";
                                    String compressedFile = destFile;
                                    using (var uncompressedOutStrm = new FileStream(uncompressedFile, FileMode.CreateNew, FileAccess.Write))
                                    {
                                        using (var compressedInStrm = new FileStream(destFile, FileMode.Open, FileAccess.Read))
                                        {
                                            using (var bz2UncompressorStrm = new Ionic.BZip2.BZip2InputStream(compressedInStrm, true) /* outer 'using' statement will close FileStream*/ )
                                            {
                                                int count = 0;
                                                int bufsize = 1024 * 1024;
                                                byte[] buf = new byte[bufsize];

                                                // EOF returns -1, see http://dotnetzip.codeplex.com/workitem/16069 
                                                while (0 < (count = bz2UncompressorStrm.Read(buf, 0, bufsize)))
                                                {
                                                    uncompressedOutStrm.Write(buf, 0, count);
                                                }
                                            }
                                        }
                                    }
                                    File.Delete(compressedFile);
                                    File.Move(uncompressedFile, compressedFile);
                                    if (File.Exists(uncompressedFile))
                                    {
                                        String errMsg = "Extra file left around called " + uncompressedFile + " when creating " + destFile;
                                        logger.Error(errMsg);
                                        throw new IOException(errMsg);
                                    }
                                }

                                // assert
                                if (!File.Exists(destFile))
                                {
                                    String errMsg = "Failed to create " + destFile + " , because the file is missing";
                                    logger.Error(errMsg);
                                    throw new IOException(errMsg);
                                }

                                newData = cmd.destTO;
                                result = true;
                            }
                            else
                            {
                                details = "Data store combination not supported";
                            }
                        }
                        // Create volume from a template?
                        else if (srcTemplateObjectTO != null && destVolumeObjectTO != null)
                        {
                            // VolumeObjectTO guesses file extension based on existing files
                            // this can be wrong if the previous file had a different file type
                            var guessedDestFile = destVolumeObjectTO.FullFileName;
                            if (File.Exists(guessedDestFile))
                            {
                                logger.Info("Deleting existing file " + guessedDestFile);
                                File.Delete(guessedDestFile);
                            }

                            destVolumeObjectTO.format = srcTemplateObjectTO.format;
                            destFile = destVolumeObjectTO.FullFileName;
                            if (File.Exists(destFile))
                            {
                                logger.Info("Deleting existing file " + destFile);
                                File.Delete(destFile);
                            }

                            string srcFile = srcTemplateObjectTO.FullFileName;
                            if (!File.Exists(srcFile))
                            {
                                details = "Local template file missing from " + srcFile;
                            }
                            else
                            {
                                // TODO: thin provision instead of copying the full file.
                                File.Copy(srcFile, destFile);
                                VolumeObjectTO volume = new VolumeObjectTO();
                                volume.path = destFile;
                                volume.dataStore = destVolumeObjectTO.dataStore;
                                volume.name = destVolumeObjectTO.name;
                                volume.size = ulong.Parse(destVolumeObjectTO.size.ToString());
                                volume.format = destVolumeObjectTO.format;
                                volume.nfsDataStore = destVolumeObjectTO.nfsDataStore;
                                volume.primaryDataStore = destVolumeObjectTO.primaryDataStore;
                                JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, volume);
                                newData = ansObj;
                                result = true;
                            }
                        }
                        else if (srcVolumeObjectTO != null && destVolumeObjectTO != null)
                        {
                            var guessedDestFile = destVolumeObjectTO.FullFileName;
                            if (File.Exists(guessedDestFile))
                            {
                                logger.Info("Deleting existing file " + guessedDestFile);
                                File.Delete(guessedDestFile);
                            }

                            destVolumeObjectTO.format = srcVolumeObjectTO.format;
                            destFile = destVolumeObjectTO.FullFileName;
                            if (File.Exists(destFile))
                            {
                                logger.Info("Deleting existing file " + destFile);
                                File.Delete(destFile);
                            }

                            string srcFile = srcVolumeObjectTO.FullFileName;
                            if (!File.Exists(srcFile))
                            {
                                details = "Local template file missing from " + srcFile;
                            }
                            else
                            {
                                // Create the directory before copying the files. CreateDirectory
                                // doesn't do anything if the directory is already present.
                                Directory.CreateDirectory(Path.GetDirectoryName(destFile));
                                File.Copy(srcFile, destFile);
                                // Create volumeto object deserialize and send it
                                destVolumeObjectTO.path = destFile;
                                JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
                                newData = ansObj;
                                result = true;
                            }
                        }
                        else if (srcVolumeObjectTO != null && destTemplateObjectTO != null)
                        {
                            var guessedDestFile = destTemplateObjectTO.FullFileName;
                            if (File.Exists(guessedDestFile))
                            {
                                logger.Info("Deleting existing file " + guessedDestFile);
                                File.Delete(guessedDestFile);
                            }

                            destTemplateObjectTO.format = srcVolumeObjectTO.format;
                            destFile = destTemplateObjectTO.FullFileName;
                            if (File.Exists(destFile))
                            {
                                logger.Info("Deleting existing file " + destFile);
                                File.Delete(destFile);
                            }

                            string srcFile = srcVolumeObjectTO.FullFileName;
                            if (!File.Exists(srcFile))
                            {
                                details = "Local template file missing from " + srcFile;
                            }
                            else
                            {
                                // Create the directory before copying the files. CreateDirectory
                                // doesn't do anything if the directory is already present.
                                Directory.CreateDirectory(Path.GetDirectoryName(destFile));
                                File.Copy(srcFile, destFile);

                                FileInfo destFileInfo = new FileInfo(destFile);
                                // Write the template.properties file
                                PostCreateTemplate(Path.GetDirectoryName(destFile), destTemplateObjectTO.id, destTemplateObjectTO.name,
                                    destFileInfo.Length.ToString(), srcVolumeObjectTO.size.ToString(), destTemplateObjectTO.format);

                                TemplateObjectTO destTemplateObject = new TemplateObjectTO();
                                destTemplateObject.size = srcVolumeObjectTO.size.ToString();
                                destTemplateObject.format = srcVolumeObjectTO.format;
                                destTemplateObject.path = destFile;
                                destTemplateObject.nfsDataStoreTO = destTemplateObjectTO.nfsDataStoreTO;
                                destTemplateObject.checksum = destTemplateObjectTO.checksum;
                                newData = destTemplateObject;
                                JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.TemplateObjectTO, destTemplateObject);
                                newData = ansObj;
                                result = true;
                            }
                        }
                        else
                        {
                            details = "Data store combination not supported";
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Test by providing wrong key
                    details = CloudStackTypes.CopyCommand + " failed on exception, " + ex.Message;
                    logger.Error(details, ex);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    newData = newData,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.CopyCmdAnswer);
            }
        }

        private static void PostCreateTemplate(string path, string templateId, string templateUuid, string physicalSize, string virtualSize, string format)
        {
            string templatePropFile = Path.Combine(path, "template.properties");
            using (StreamWriter sw = new StreamWriter(File.Open(templatePropFile, FileMode.Create), Encoding.GetEncoding("iso-8859-1")))
            {
                sw.NewLine = "\n";
                sw.WriteLine("id=" + templateId);
                sw.WriteLine("filename=" + templateUuid + "." + format);
                sw.WriteLine(format + ".filename=" + templateUuid + "." + format);
                sw.WriteLine("uniquename=" + templateUuid);
                sw.WriteLine(format + "=true");
                sw.WriteLine("virtualsize=" + virtualSize);
                sw.WriteLine(format + ".virtualsize=" + virtualSize);
                sw.WriteLine("size=" + physicalSize);
                sw.WriteLine("vhd.size=" + physicalSize);
                sw.WriteLine("public=false");
            }
        }

        private static bool VerifyChecksum(string destFile, string checksum)
        {
            string localChecksum = BitConverter.ToString(CalcFileChecksum(destFile)).Replace("-", "").ToLower();
            logger.Debug("Checksum of " + destFile + " is " + checksum);
            if (checksum.Equals(localChecksum))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Match implmentation of DownloadManagerImpl.computeCheckSum
        /// </summary>
        /// <param name="destFile"></param>
        /// <returns></returns>
        private static byte[] CalcFileChecksum(string destFile)
        {
            // TODO:  Add unit test to verify that checksum algorithm has not changed.
            using (MD5 md5 = MD5.Create())
            {
                using (FileStream stream = File.OpenRead(destFile))
                {
                    return md5.ComputeHash(stream);
                }
            }
        }

        private static void DownloadS3ObjectToFile(string srcObjectKey, S3TO srcS3TO, string destFile)
        {
            AmazonS3Config S3Config = new AmazonS3Config
            {
                ServiceURL = srcS3TO.endpoint,
                CommunicationProtocol = Amazon.S3.Model.Protocol.HTTP
            };

            if (srcS3TO.httpsFlag)
            {
                S3Config.CommunicationProtocol = Protocol.HTTPS;
            }

            try
            {
                using (AmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(srcS3TO.accessKey, srcS3TO.secretKey, S3Config))
                {
                    GetObjectRequest getObjectRequest = new GetObjectRequest().WithBucketName(srcS3TO.bucketName).WithKey(srcObjectKey);

                    using (S3Response getObjectResponse = client.GetObject(getObjectRequest))
                    {
                        using (Stream s = getObjectResponse.ResponseStream)
                        {
                            using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write))
                            {
                                byte[] data = new byte[524288];
                                int bytesRead = 0;
                                do
                                {
                                    bytesRead = s.Read(data, 0, data.Length);
                                    fs.Write(data, 0, bytesRead);
                                }
                                while (bytesRead > 0);
                                fs.Flush();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string errMsg = "Download from S3 url" + srcS3TO.endpoint + " said: " + ex.Message;
                logger.Error(errMsg, ex);
                throw new Exception(errMsg, ex);
            }
        }

        // POST api/HypervResource/GetStorageStatsCommand
        [HttpPost]
        [ActionName(CloudStackTypes.GetStorageStatsCommand)]
        public JContainer GetStorageStatsCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.GetStorageStatsCommand + cmd.ToString());
                bool result = false;
                string details = null;
                long capacity = 0;
                long available = 0;
                long used = 0;
                try
                {
                    StoragePoolType poolType;
                    string poolId = (string)cmd.id;
                    string hostPath = null;
                    if (!Enum.TryParse<StoragePoolType>((string)cmd.pooltype, out poolType))
                    {
                        details = "Request to get unsupported pool type: " + ((string)cmd.pooltype == null ? "NULL" : (string)cmd.pooltype) + "in cmd " +
                            JsonConvert.SerializeObject(cmd);
                        logger.Error(details);
                    }
                    else if (poolType == StoragePoolType.Filesystem)
                    {
                        hostPath = (string)cmd.localPath;;
                        GetCapacityForLocalPath(hostPath, out capacity, out available);
                        used = capacity - available;
                        result = true;
                    }
                    else if (poolType == StoragePoolType.NetworkFilesystem)
                    {
                        string sharePath = config.getPrimaryStorage((string)cmd.id);
                        if (sharePath != null)
                        {
                            hostPath = sharePath;
                            Utils.GetShareDetails(sharePath, out capacity, out available);
                            used = capacity - available;
                            result = true;
                        }
                    }
                    else
                    {
                        result = false;
                    }

                    if (result)
                    {
                        logger.Debug(CloudStackTypes.GetStorageStatsCommand + " set used bytes for " + hostPath + " to " + used);
                    }
                }
                catch (Exception ex)
                {
                    details = CloudStackTypes.GetStorageStatsCommand + " failed on exception" + ex.Message;
                    logger.Error(details, ex);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    capacity = capacity,
                    used = used,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetStorageStatsAnswer);
            }
        }

        // POST api/HypervResource/GetHostStatsCommand
        [HttpPost]
        [ActionName(CloudStackTypes.GetHostStatsCommand)]
        public JContainer GetHostStatsCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.GetHostStatsCommand + cmd.ToString());
                bool result = false;
                string details = null;
                object hostStats = null;

                var entityType = "host";
                ulong totalMemoryKBs;
                ulong freeMemoryKBs;
                double networkReadKBs;
                double networkWriteKBs;
                double cpuUtilization;

                try
                {
                    long hostId = (long)cmd.hostId;
                    wmiCallsV2.GetMemoryResources(out totalMemoryKBs, out freeMemoryKBs);
                    wmiCallsV2.GetProcessorUsageInfo(out cpuUtilization);

                    // TODO: can we assume that the host has only one adaptor?
                    string tmp;
                    var privateNic = GetNicInfoFromIpAddress(config.PrivateIpAddress, out tmp);
                    var nicStats = privateNic.GetIPv4Statistics();  //TODO: add IPV6 support, currentl
                    networkReadKBs = nicStats.BytesReceived;
                    networkWriteKBs = nicStats.BytesSent;

                    // Generate GetHostStatsAnswer
                    hostStats = new
                    {
                        hostId = hostId,
                        entityType = entityType,
                        cpuUtilization = cpuUtilization,
                        networkReadKBs = networkReadKBs,
                        networkWriteKBs = networkWriteKBs,
                        totalMemoryKBs = (double)totalMemoryKBs,
                        freeMemoryKBs = (double)freeMemoryKBs
                    };
                    result = true;
                }
                catch (Exception ex)
                {
                    details = CloudStackTypes.GetHostStatsCommand + " failed on exception" + ex.Message;
                    logger.Error(details, ex);
                }

                object ansContent = new
                {
                    result = result,
                    hostStats = hostStats,
                    details = details,
                    contextMap = contextMap
                };
                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetHostStatsAnswer);
            }
        }

        // POST api/HypervResource/PrepareForMigrationCommand
        [HttpPost]
        [ActionName(CloudStackTypes.PrepareForMigrationCommand)]
        public JContainer PrepareForMigrationCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.PrepareForMigrationCommand + cmd.ToString());

                string details = null;
                bool result = true;

                try
                {
                    details = "NOP - success";
                }
                catch (Exception sysEx)
                {
                    result = false;
                    details = CloudStackTypes.PrepareForMigrationCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PrepareForMigrationAnswer);
            }
        }

        // POST api/HypervResource/MigrateCommand
        [HttpPost]
        [ActionName(CloudStackTypes.MigrateCommand)]
        public JContainer MigrateCommand([FromBody]dynamic cmd)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(CloudStackTypes.MigrateCommand + cmd.ToString());

                string details = null;
                bool result = false;

                try
                {
                    string vm = (string)cmd.vmName;
                    string destination = (string)cmd.destIp;
                    wmiCallsV2.MigrateVm(vm, destination);
                    result = true;
                }
                catch (Exception sysEx)
                {
                    details = CloudStackTypes.MigrateCommand + " failed due to " + sysEx.Message;
                    logger.Error(details, sysEx);
                }

                object ansContent = new
                {
                    result = result,
                    details = details,
                    contextMap = contextMap
                };

                return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.MigrateAnswer);
            }
        }

        // POST api/HypervResource/StartupCommand
        [HttpPost]
        [ActionName(CloudStackTypes.StartupCommand)]
        public JContainer StartupCommand([FromBody]dynamic cmdArray)
        {
            using (log4net.NDC.Push(Guid.NewGuid().ToString()))
            {
                logger.Info(cmdArray.ToString());
                // Log agent configuration
                logger.Info("Agent StartupRoutingCommand received " + cmdArray.ToString());
                dynamic strtRouteCmd = cmdArray[0][CloudStackTypes.StartupRoutingCommand];

                // Insert networking details
                string privateIpAddress = strtRouteCmd.privateIpAddress;
                string subnet;
                System.Net.NetworkInformation.NetworkInterface privateNic = GetNicInfoFromIpAddress(privateIpAddress, out subnet);
                strtRouteCmd.privateIpAddress = privateIpAddress;
                strtRouteCmd.privateNetmask = subnet;
                strtRouteCmd.privateMacAddress = privateNic.GetPhysicalAddress().ToString();
                string storageip = strtRouteCmd.storageIpAddress;
                System.Net.NetworkInformation.NetworkInterface storageNic = GetNicInfoFromIpAddress(storageip, out subnet);

                strtRouteCmd.storageIpAddress = storageip;
                strtRouteCmd.storageNetmask = subnet;
                strtRouteCmd.storageMacAddress = storageNic.GetPhysicalAddress().ToString();
                strtRouteCmd.gatewayIpAddress = storageNic.GetPhysicalAddress().ToString();

                strtRouteCmd.caps = "hvm";

                dynamic details = strtRouteCmd.hostDetails;
                if (details != null)
                {
                    string productVersion = System.Environment.OSVersion.Version.Major.ToString() + "." +
                        System.Environment.OSVersion.Version.Minor.ToString();
                    details.Add("product_version", productVersion);
                }

                // Detect CPUs, speed, memory
                uint cores;
                uint mhz;
                uint sockets;
                wmiCallsV2.GetProcessorResources(out sockets, out cores, out mhz);
                strtRouteCmd.cpus = cores;
                strtRouteCmd.speed = mhz;
                strtRouteCmd.cpuSockets = sockets;
                ulong memoryKBs;
                ulong freeMemoryKBs;
                wmiCallsV2.GetMemoryResources(out memoryKBs, out freeMemoryKBs);
                strtRouteCmd.memory = memoryKBs * 1024;   // Convert to bytes

                // Need 2 Gig for DOM0, see http://technet.microsoft.com/en-us/magazine/hh750394.aspx
                strtRouteCmd.dom0MinMemory = config.ParentPartitionMinMemoryMb * 1024 * 1024;  // Convert to bytes

                // Insert storage pool details.
                //
                // Read the localStoragePath for virtual disks from the Hyper-V configuration
                // See http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/05/06/managing-the-default-virtual-machine-location-with-hyper-v.aspx
                // for discussion of Hyper-V file locations paths.
                string localStoragePath = wmiCallsV2.GetDefaultVirtualDiskFolder();
                if (localStoragePath != null)
                {
                    // GUID arbitrary.  Host agents deals with storage pool in terms of localStoragePath.
                    // We use HOST guid.
                    string poolGuid = strtRouteCmd.guid;

                    if (poolGuid == null)
                    {
                        poolGuid = Guid.NewGuid().ToString();
                        logger.InfoFormat("Setting Startup StoragePool GUID to " + poolGuid);
                    }
                    else
                    {
                        logger.InfoFormat("Setting Startup StoragePool GUID same as HOST, i.e. " + poolGuid);
                    }

                    long capacity;
                    long available;
                    GetCapacityForLocalPath(localStoragePath, out capacity, out available);

                    logger.Debug(CloudStackTypes.StartupStorageCommand + " set available bytes to " + available);

                    string ipAddr = strtRouteCmd.privateIpAddress;
                    var vmStates = wmiCallsV2.GetVmSync(config.PrivateIpAddress);
                    strtRouteCmd.vms = Utils.CreateCloudStackMapObject(vmStates);

                    StoragePoolInfo pi = new StoragePoolInfo(
                        poolGuid.ToString(),
                        ipAddr,
                        localStoragePath,
                        localStoragePath,
                        StoragePoolType.Filesystem.ToString(),
                        capacity,
                        available);

                    // Build StartupStorageCommand using an anonymous type
                    // See http://stackoverflow.com/a/6029228/939250
                    object ansContent = new
                    {
                        poolInfo = pi,
                        guid = pi.uuid,
                        dataCenter = strtRouteCmd.dataCenter,
                        resourceType = StorageResourceType.STORAGE_POOL.ToString(),  // TODO: check encoding
                        contextMap = contextMap
                    };
                    JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.StartupStorageCommand, ansContent);
                    cmdArray.Add(ansObj);
                }

                // Convert result to array for type correctness?
                logger.Info(CloudStackTypes.StartupCommand + " result is " + cmdArray.ToString());
                return cmdArray;
            }
        }

        public static System.Net.NetworkInformation.NetworkInterface GetNicInfoFromIpAddress(string ipAddress, out string subnet)
        {
            System.Net.NetworkInformation.NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
            System.Net.NetworkInformation.NetworkInterface defaultnic = null;
            foreach (var nic in nics)
            {
                subnet = null;
                defaultnic = nic;
                // TODO: use to remove NETMASK and MAC from the config file, and to validate the IPAddress.
                var nicProps = nic.GetIPProperties();
                bool found = false;
                foreach (var addr in nicProps.UnicastAddresses)
                {
                    if (addr.Address.Equals(IPAddress.Parse(ipAddress)))
                    {
                        subnet = addr.IPv4Mask.ToString();
                        found = true;
                    }
                }
                if (!found)
                {
                    continue;
                }
                return nic;
            }
            var defaultSubnet = defaultnic.GetIPProperties().UnicastAddresses[0];
            subnet = defaultSubnet.IPv4Mask.ToString();
            return defaultnic;
        }

        public static void GetCapacityForLocalPath(string localStoragePath, out long capacityBytes, out long availableBytes)
        {
            // NB: DriveInfo does not work for remote folders (http://stackoverflow.com/q/1799984/939250)
            // DriveInfo requires a driver letter...
            string fullPath = Path.GetFullPath(localStoragePath);
            System.IO.DriveInfo poolInfo = new System.IO.DriveInfo(fullPath);
            capacityBytes = poolInfo.TotalSize;
            availableBytes = poolInfo.AvailableFreeSpace;

            // Don't allow all of the Root Device to be used for virtual disks
            if (poolInfo.RootDirectory.Name.ToLower().Equals(config.RootDeviceName))
            {
                availableBytes -= config.RootDeviceReservedSpaceBytes;
                availableBytes = availableBytes > 0 ? availableBytes : 0;
                capacityBytes -= config.RootDeviceReservedSpaceBytes;
                capacityBytes = capacityBytes > 0 ? capacityBytes : 0;
            }
        }
    }
}
