﻿// 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 System;
using CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION.V2;
using System.Management;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.IO;
using log4net;
using HypervResource;
using CloudStack.Plugin.AgentShell;
using System.Collections.Generic;
using NSubstitute;
using System.Web.Http;
using Xunit;

namespace ServerResource.Tests
{
    public class HypervResourceController1Test
    {
        protected static string testCifsUrl = AgentSettings.Default.testCifsUrl;
        protected static string testCifsPath = AgentSettings.Default.testCifsPath;
        protected static String testPrimaryDataStoreHost = HypervResourceController.config.StorageIpAddress;
        protected static String testS3TemplateName = AgentSettings.Default.testS3TemplateName;
        protected static String testCifsTemplateName = AgentSettings.Default.testS3TemplateName;
        protected static String testSystemVMTemplateName = AgentSettings.Default.testSystemVMTemplateName;
        protected static String testSystemVMTemplateNameNoExt = AgentSettings.Default.testSystemVMTemplateNameNoExt;
        protected static String testLocalStoreUUID = "5fe2bad3-d785-394e-9949-89786b8a63d2";
        protected static String testLocalStorePath = Path.Combine(AgentSettings.Default.hyperv_plugin_root, "var", "test", "storagepool");
        protected static String testSecondaryStoreLocalPath = Path.Combine(AgentSettings.Default.hyperv_plugin_root, "var", "test", "secondary");

        // TODO: differentiate between NFS and HTTP template URLs.
        protected static String testSampleTemplateUUID = "TestCopiedLocalTemplate.vhdx";
        protected static String testSampleTemplateURL = testSampleTemplateUUID;

        // test volumes are both a minimal size vhdx.  Changing the extension to .vhd makes on corrupt.
        protected static String testSampleVolumeWorkingUUID = "TestVolumeLegit.vhdx";
        protected static String testSampleVolumeCorruptUUID = "TestVolumeCorrupt.vhd";
        protected static String testSampleVolumeTempUUID = "TestVolumeTemp.vhdx";
        protected static String testSampleVolumeTempUUIDNoExt = "TestVolumeTemp";
        protected static String testSampleVolumeWorkingURIJSON;
        protected static String testSampleVolumeCorruptURIJSON;
        protected static String testSampleVolumeTempURIJSON;

        protected static String testSampleTemplateURLJSON;
        protected static String testLocalStorePathJSON;

        protected static IWmiCallsV2 wmiCallsV2;


        private static ILog s_logger = LogManager.GetLogger(typeof(HypervResourceController1Test));

        /// <summary>
        /// Test WmiCalls to which incoming HTTP POST requests are dispatched.
        /// 
        /// TODO: revise beyond first approximation
        /// First approximation is a quick port of the existing Java tests for Hyper-V server resource.
        /// A second approximation would use the AgentShell settings files directly.
        /// A third approximation would look to invoke ServerResource methods via an HTTP request
        /// </summary>

        public HypervResourceController1Test()
        {
            wmiCallsV2 = Substitute.For<IWmiCallsV2>();
            //AgentService.ConfigServerResource();
            HypervResourceController.config.PrivateMacAddress = AgentSettings.Default.private_mac_address;
            HypervResourceController.config.PrivateNetmask = AgentSettings.Default.private_ip_netmask;
            HypervResourceController.config.StorageIpAddress = HypervResourceController.config.PrivateIpAddress;
            HypervResourceController.config.StorageMacAddress = HypervResourceController.config.PrivateMacAddress;
            HypervResourceController.config.StorageNetmask = HypervResourceController.config.PrivateNetmask;


            // Used to create existing StoragePool in preparation for the ModifyStoragePool
            testLocalStoreUUID = AgentSettings.Default.local_storage_uuid.ToString();

            // Make sure secondary store is available.
            string fullPath = Path.GetFullPath(testSecondaryStoreLocalPath);
            s_logger.Info("Test secondary storage in " + fullPath);
            DirectoryInfo testSecondarStoreDir = new DirectoryInfo(fullPath);
            if (!testSecondarStoreDir.Exists)
            {
                try
                {
                    testSecondarStoreDir.Create();
                }
                catch (System.IO.IOException ex)
                {
                    throw new NotImplementedException("Need to be able to create the folder " + testSecondarStoreDir.FullName + " failed due to " + ex.Message);
                }
            }

            // Convert to secondary storage string to canonical path
            testSecondaryStoreLocalPath = testSecondarStoreDir.FullName;
            AgentSettings.Default.local_secondary_storage_path = testSecondaryStoreLocalPath;

            // Make sure local primary storage is available
            DirectoryInfo testPoolDir = new DirectoryInfo(testLocalStorePath);
            //Assert.True(testPoolDir.Exists, "To simulate local file system Storage Pool, you need folder at " + testPoolDir.FullName);

            // Convert to local primary storage string to canonical path
            testLocalStorePath = testPoolDir.FullName;
            AgentSettings.Default.local_storage_path = testLocalStorePath;

            // Clean up old test files in local storage folder
            FileInfo testVolWorks = new FileInfo(Path.Combine(testLocalStorePath, testSampleVolumeWorkingUUID));
            // Assert.True(testVolWorks.Exists, "Create a working virtual disk at " + testVolWorks.FullName);           
            
            testSampleTemplateURLJSON = JsonConvert.SerializeObject(testSampleTemplateUUID);
            s_logger.Info("Created " + testSampleTemplateURLJSON + " in local storage.");           


            // Capture other JSON encoded paths
            testSampleVolumeWorkingURIJSON = Newtonsoft.Json.JsonConvert.SerializeObject(testVolWorks.FullName);
            testLocalStorePathJSON = JsonConvert.SerializeObject(testLocalStorePath);

            // TODO: may need to initialise the server resource in future.
            //    s_hypervresource.initialize();

            // Verify sample template is in place storage pool
            s_logger.Info("setUp complete, sample StoragePool at " + testLocalStorePathJSON
                      + " sample template at " + testSampleTemplateURLJSON);
        }

        private String CreateTestDiskImageFromExistingImage(FileInfo srcFile,
        String dstPath,
        String dstFileName)
        {
            var newFullname = Path.Combine(dstPath, dstFileName);
            var newFileInfo = new FileInfo(newFullname);
            if (!newFileInfo.Exists)
            {
                newFileInfo = srcFile.CopyTo(newFullname);
            }
            newFileInfo.Refresh();
            Assert.True(newFileInfo.Exists, "Attempted to create " + newFullname + " from " + newFileInfo.FullName);

            return JsonConvert.SerializeObject(newFileInfo.FullName);
        }
        
        [Fact]
        public void TestCreateCommand()
        {
            DirectoryInfo localStorePath = new DirectoryInfo(testLocalStorePath);
            if (!localStorePath.Exists)
            {
                try
                {
                    localStorePath.Create();
                }
                catch (System.IO.IOException ex)
                {
                    throw new NotImplementedException("Need to be able to create the folder " + localStorePath.FullName + " failed due to " + ex.Message);
                }
            }

            FileInfo sampleTemplateFile = new FileInfo(Path.Combine(testLocalStorePath, testSampleTemplateUUID));
            if (!sampleTemplateFile.Exists)
            {
                //Create a file to write to.
                using (StreamWriter sw = sampleTemplateFile.CreateText())
                {
                    sw.WriteLine("This is fake template file for test");
                }
            }
            var counter = 0;
            wmiCallsV2.When(x => x.CreateDynamicVirtualHardDisk(Arg.Any<ulong>(), Arg.Any<String>())).Do(x => counter++);
            // TODO: Need sample to update the test.
            // Arrange
            String createCmd = "{\"volId\":10,\"pool\":{\"id\":201,\"uuid\":\"" + testLocalStoreUUID + "\",\"host\":\"" + HypervResourceController.config.StorageIpAddress + "\"" +
                            ",\"path\":" + testLocalStorePathJSON + ",\"port\":0,\"type\":\"Filesystem\"},\"diskCharacteristics\":{\"size\":0," +
                            "\"tags\":[],\"type\":\"ROOT\",\"name\":\"ROOT-9\",\"useLocalStorage\":true,\"recreatable\":true,\"diskOfferingId\":11," +
                            "\"volumeId\":10,\"hyperType\":\"Hyperv\"},\"templateUrl\":" + testSampleTemplateURLJSON + ",\"contextMap\":{},\"wait\":0}";
            dynamic jsonCreateCmd = JsonConvert.DeserializeObject(createCmd);
            HypervResourceController rsrcServer = new HypervResourceController();
            HypervResourceController.wmiCallsV2 = wmiCallsV2;

            Assert.True(Directory.Exists(testLocalStorePath), testLocalStorePath + " does not exist ");
            string filePath = Path.Combine(testLocalStorePath, (string)JsonConvert.DeserializeObject(testSampleTemplateURLJSON));
            Assert.True(File.Exists(filePath), "The template we make volumes from is missing from path " + filePath);
            int fileCount = Directory.GetFiles(testLocalStorePath).Length;
            s_logger.Debug(" test local store has " + fileCount + "files");

            // Act
            // Test requires there to be a template at the tempalteUrl, which is its location in the local file system.
            dynamic jsonResult = rsrcServer.CreateCommand(jsonCreateCmd);
            s_logger.Debug("CreateDynamicVirtualHardDisk method is called " + counter + " times");

            //Assert.Equal(counter, 1);

            JObject ansAsProperty2 = jsonResult[0];
            dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.CreateAnswer);
            Assert.NotNull(ans);
            Assert.True((bool)ans.result, "Failed to CreateCommand due to " + (string)ans.result);
            Assert.Equal(Directory.GetFiles(testLocalStorePath).Length, fileCount + 1);
            FileInfo newFile = new FileInfo((string)ans.volume.path);
            Assert.True(newFile.Length > 0, "The new file should have a size greater than zero");
            newFile.Delete();
            sampleTemplateFile.Delete();
        }

        [Fact]
        public void TestDestroyCommand()
        {
            testSampleVolumeTempURIJSON = "\"storagepool\"";
            // Arrange
            String destoryCmd = //"{\"volume\":" + getSampleVolumeObjectTO() + "}";
                            "{\"volume\":{\"name\":\"" + testSampleVolumeTempUUIDNoExt
                                    + "\",\"storagePoolType\":\"Filesystem\","
                                    + "\"mountPoint\":"
                                    + testLocalStorePathJSON
                                   + ",\"path\":" + testSampleVolumeTempURIJSON
                                    + ",\"storagePoolUuid\":\"" + testLocalStoreUUID
                                    + "\","
                                    + "\"type\":\"ROOT\",\"id\":9,\"size\":0}}";

            ImageManagementService imgmgr = new ImageManagementService();
            wmiCallsV2.GetImageManagementService().Returns(imgmgr);

            HypervResourceController rsrcServer = new HypervResourceController();
            HypervResourceController.wmiCallsV2 = wmiCallsV2;

            dynamic jsonDestoryCmd = JsonConvert.DeserializeObject(destoryCmd);

            // Act
            dynamic destoryAns = rsrcServer.DestroyCommand(jsonDestoryCmd);

            // Assert
            JObject ansAsProperty2 = destoryAns[0];
            dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.Answer);
            String path = jsonDestoryCmd.volume.path;
            Assert.True((bool)ans.result, "DestroyCommand did not succeed " + ans.details);
            Assert.True(!File.Exists(path), "Failed to delete file " + path);
        }

        [Fact]
        public void TestStartCommand()
        {
            ComputerSystem system = new ComputerSystem();
            wmiCallsV2.DeployVirtualMachine(Arg.Any<Object>(), Arg.Any<string>()).Returns(system);

            // Arrange
            HypervResourceController rsrcServer = new HypervResourceController();
            HypervResourceController.wmiCallsV2 = wmiCallsV2;
            String sample = getSampleStartCommand();


            dynamic jsonStartCmd = JsonConvert.DeserializeObject(sample);

            // Act
            dynamic startAns = rsrcServer.StartCommand(jsonStartCmd);

            // Assert
            Assert.NotNull(startAns[0][CloudStackTypes.StartAnswer]);
            Assert.True((bool)startAns[0][CloudStackTypes.StartAnswer].result, "StartCommand did not succeed " + startAns[0][CloudStackTypes.StartAnswer].details);

            Assert.Null((string)startAns[0][CloudStackTypes.StartAnswer].details);            
        }

        [Fact]
        public void TestStopCommand()
        {
            //string vmName = "Test VM";
            var counter = 0;
            wmiCallsV2.When(x => x.DestroyVm(Arg.Any<Object>())).Do(x => counter++);

            // Arrange
            HypervResourceController rsrcServer = new HypervResourceController();
            HypervResourceController.wmiCallsV2 = wmiCallsV2;

            String sampleStop = "{\"isProxy\":false,\"vmName\":\"i-2-17-VM\",\"contextMap\":{},\"wait\":0}";
            dynamic jsonStopCmd = JsonConvert.DeserializeObject(sampleStop);

            // Act
            dynamic stopAns = rsrcServer.StopCommand(jsonStopCmd);

            // Assert VM is gone!
            Assert.NotNull(stopAns[0][CloudStackTypes.StopAnswer]);
            Assert.True((bool)stopAns[0][CloudStackTypes.StopAnswer].result, "StopCommand did not succeed " + stopAns[0][CloudStackTypes.StopAnswer].details);

            Assert.Null((string)stopAns[0][CloudStackTypes.StopAnswer].details);
            Assert.Equal<int>(counter, 1);
        }

        public static String getSamplePrimaryDataStoreInfo()
        {
            String samplePrimaryDataStoreInfo =
            "{\"org.apache.cloudstack.storage.to.PrimaryDataStoreTO\":" +
                "{\"uuid\":\"" + testLocalStoreUUID + "\"," +
                "\"id\":201," +
                "\"host\":\"" + testPrimaryDataStoreHost + "\"," +
                "\"type\":\"Filesystem\"," +  // Not used in PrimaryDataStoreTO
                "\"poolType\":\"Filesystem\"," +  // Not used in PrimaryDataStoreTO
                "\"path\":" + testLocalStorePathJSON + "," +
                "\"port\":0}" +
            "}";
            return samplePrimaryDataStoreInfo;
        }

        public static String getSampleVolumeObjectTO()
        {
            String sampleVolumeObjectTO =
                    "{\"org.apache.cloudstack.storage.to.VolumeObjectTO\":" +
                        "{\"uuid\":\"19ae8e67-cb2c-4ab4-901e-e0b864272b59\"," +
                        "\"volumeType\":\"ROOT\"," +
                        "\"format\":\"VHDX\"," +
                        "\"dataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
                        "\"name\":\"" + testSampleVolumeTempUUIDNoExt + "\"," +
                        "\"size\":52428800," +
                        "\"volumeId\":10," +
                //                            "\"vmName\":\"i-3-5-VM\"," +  // TODO: do we have to fill in the vmName?
                        "\"accountId\":3,\"id\":10}" +
                    "}";  // end of destTO 
            return sampleVolumeObjectTO;
        }

        public static String getSampleStartCommand()
        {
            String sample = "{\"vm\":{\"id\":17,\"name\":\"i-2-17-VM\",\"type\":\"User\",\"cpus\":1,\"speed\":500," +
                                "\"minRam\":536870912,\"maxRam\":536870912,\"arch\":\"x86_64\"," +
                                "\"os\":\"CentOS 6.0 (64-bit)\",\"bootArgs\":\"\",\"rebootOnCrash\":false," +
                                "\"enableHA\":false,\"limitCpuUse\":false,\"vncPassword\":\"31f82f29aff646eb\"," +
                                "\"params\":{},\"uuid\":\"8b030b6a-0243-440a-8cc5-45d08815ca11\"" +
                            ",\"disks\":[" +
                               "{\"data\":" + getSampleVolumeObjectTO() + ",\"diskSeq\":0,\"type\":\"ROOT\"}," +
                               "{\"diskSeq\":1,\"type\":\"ISO\"}" +
                            "]," +
                            "\"nics\":[" +
                                    "{\"deviceId\":0,\"networkRateMbps\":100,\"defaultNic\":true,\"uuid\":\"99cb4813-23af-428c-a87a-2d1899be4f4b\"," +
                                    "\"ip\":\"10.1.1.67\",\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\"," +
                                    "\"mac\":\"02:00:51:2c:00:0e\",\"dns1\":\"4.4.4.4\",\"broadcastType\":\"Vlan\",\"type\":\"Guest\"," +
                                    "\"broadcastUri\":\"vlan://261\",\"isolationUri\":\"vlan://261\",\"isSecurityGroupEnabled\":false}" +
                            "]},\"contextMap\":{},\"wait\":0}";
            return sample;
        }        
    }
}
