// 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.

package com.cloud.vm;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ScaleVmAnswer;
import com.cloud.agent.api.ScaleVmCommand;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.MigrateWithStorageAnswer;
import com.cloud.agent.api.MigrateWithStorageCommand;
import com.cloud.agent.api.MigrateWithStorageReceiveAnswer;
import com.cloud.agent.api.MigrateWithStorageReceiveCommand;
import com.cloud.agent.api.MigrateWithStorageSendAnswer;
import com.cloud.agent.api.MigrateWithStorageSendCommand;
import com.cloud.agent.api.MigrateWithStorageCompleteAnswer;
import com.cloud.agent.api.MigrateWithStorageCompleteCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.NetworkManager;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.*;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshotManager;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;

import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;

import org.junit.Test;
import org.junit.Before;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.*;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public class VirtualMachineManagerImplTest {

        @Spy VirtualMachineManagerImpl _vmMgr = new VirtualMachineManagerImpl();
        @Mock
        VolumeManager _storageMgr;
        @Mock
        Account _account;
        @Mock
        AccountManager _accountMgr;
        @Mock
        ConfigurationManager _configMgr;
        @Mock
        CapacityManager _capacityMgr;
        @Mock
        AgentManager _agentMgr;
        @Mock
        AccountDao _accountDao;
        @Mock
        ConfigurationDao _configDao;
        @Mock
        HostDao _hostDao;
        @Mock
        UserDao _userDao;
        @Mock
        UserVmDao _vmDao;
        @Mock
        ItWorkDao _workDao;
        @Mock
        VMInstanceDao _vmInstanceDao;
        @Mock
        VMTemplateDao _templateDao;
        @Mock
        VolumeDao _volsDao;
        @Mock
        RestoreVMCmd _restoreVMCmd;
        @Mock
        AccountVO _accountMock;
        @Mock
        UserVO _userMock;
        @Mock
        UserVmVO _vmMock;
        @Mock
        VMInstanceVO _vmInstance;
        @Mock
        HostVO _host;
        @Mock
        VMTemplateVO _templateMock;
        @Mock
        VolumeVO _volumeMock;
        @Mock
        List<VolumeVO> _rootVols;
        @Mock
        ItWorkVO _work;

        @Mock ClusterDao _clusterDao;
        @Mock HostPodDao _podDao;
        @Mock DataCenterDao _dcDao;
        @Mock DiskOfferingDao _diskOfferingDao;
        @Mock PrimaryDataStoreDao _storagePoolDao;
        @Mock StoragePoolHostDao _poolHostDao;
        @Mock NetworkManager _networkMgr;
        @Mock HypervisorGuruManager _hvGuruMgr;
        @Mock VMSnapshotManager _vmSnapshotMgr;

        // Mock objects for vm migration with storage test.
        @Mock DiskOfferingVO _diskOfferingMock;
        @Mock StoragePoolVO _srcStoragePoolMock;
        @Mock StoragePoolVO _destStoragePoolMock;
        @Mock HostVO _srcHostMock;
        @Mock HostVO _destHostMock;
        @Mock Map<VolumeVO, StoragePoolVO> _volumeToPoolMock;

        @Before
        public void setup(){
            MockitoAnnotations.initMocks(this);

            _vmMgr._templateDao = _templateDao;
            _vmMgr._volsDao = _volsDao;
            _vmMgr.volumeMgr = _storageMgr;
            _vmMgr._accountDao = _accountDao;
            _vmMgr._userDao = _userDao;
            _vmMgr._accountMgr = _accountMgr;
            _vmMgr._configMgr = _configMgr;
            _vmMgr._capacityMgr = _capacityMgr;
            _vmMgr._hostDao = _hostDao;
            _vmMgr._nodeId = 1L;
            _vmMgr._workDao = _workDao;
            _vmMgr._agentMgr = _agentMgr;
            _vmMgr._podDao = _podDao;
            _vmMgr._clusterDao = _clusterDao;
            _vmMgr._dcDao = _dcDao;
            _vmMgr._diskOfferingDao = _diskOfferingDao;
            _vmMgr._storagePoolDao = _storagePoolDao;
            _vmMgr._poolHostDao= _poolHostDao;
            _vmMgr._networkMgr = _networkMgr;
            _vmMgr._hvGuruMgr = _hvGuruMgr;
            _vmMgr._vmSnapshotMgr = _vmSnapshotMgr;
            _vmMgr._vmDao = _vmInstanceDao;

            when(_vmMock.getId()).thenReturn(314l);
            when(_vmInstance.getId()).thenReturn(1L);
            when(_vmInstance.getServiceOfferingId()).thenReturn(2L);
            when(_vmInstance.getInstanceName()).thenReturn("myVm");
            when(_vmInstance.getHostId()).thenReturn(2L);
            when(_vmInstance.getType()).thenReturn(VirtualMachine.Type.User);
            when(_host.getId()).thenReturn(1L);
            when(_hostDao.findById(anyLong())).thenReturn(null);
            when(_configMgr.getServiceOffering(anyLong())).thenReturn(getSvcoffering(512));
            when(_workDao.persist(_work)).thenReturn(_work);
            when(_workDao.update("1", _work)).thenReturn(true);
            when(_work.getId()).thenReturn("1");
            doNothing().when(_work).setStep(ItWorkVO.Step.Done);
            //doNothing().when(_volsDao).detachVolume(anyLong());
            //when(_work.setStep(ItWorkVO.Step.Done)).thenReturn("1");

        }


    @Test(expected=CloudRuntimeException.class)
    public void testScaleVM1()  throws Exception {


        DeployDestination dest = new DeployDestination(null, null, null, _host);
        long l = 1L;

        when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
        _vmMgr.migrateForScale(_vmInstance, l, dest, l);

    }

    @Test (expected=CloudRuntimeException.class)
    public void testScaleVM2()  throws Exception {

        DeployDestination dest = new DeployDestination(null, null, null, _host);
        long l = 1L;

        when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
        ServiceOfferingVO newServiceOffering = getSvcoffering(512);
        ScaleVmCommand reconfigureCmd = new ScaleVmCommand("myVmName", newServiceOffering.getCpu(),
                newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse());
        Answer answer = new ScaleVmAnswer(reconfigureCmd, true, "details");
        when(_agentMgr.send(2l, reconfigureCmd)).thenReturn(null);
        _vmMgr.reConfigureVm(_vmInstance, getSvcoffering(256), false);

    }

    @Test (expected=CloudRuntimeException.class)
    public void testScaleVM3()  throws Exception {

        /*VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);

        Long srcHostId = vm.getHostId();
        Long oldSvcOfferingId = vm.getServiceOfferingId();
        if (srcHostId == null) {
            throw new CloudRuntimeException("Unable to scale the vm because it doesn't have a host id");
        }*/

        when(_vmInstance.getHostId()).thenReturn(null);
        when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
        _vmMgr.findHostAndMigrate(VirtualMachine.Type.User, _vmInstance, 2l);

    }


    private ServiceOfferingVO getSvcoffering(int ramSize){

        long id  = 4L;
        String name = "name";
        String displayText = "displayText";
        int cpu = 1;
        //int ramSize = 256;
        int speed = 128;

        boolean ha = false;
        boolean useLocalStorage = false;

        ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, useLocalStorage, false, null, false, null, false);
        return serviceOffering;
    }

    private void initializeMockConfigForMigratingVmWithVolumes() throws OperationTimedoutException,
        ResourceUnavailableException {

        // Mock the source and destination hosts.
        when(_srcHostMock.getId()).thenReturn(5L);
        when(_destHostMock.getId()).thenReturn(6L);
        when(_hostDao.findById(5L)).thenReturn(_srcHostMock);
        when(_hostDao.findById(6L)).thenReturn(_destHostMock);

        // Mock the vm being migrated.
        when(_vmMock.getId()).thenReturn(1L);
        when(_vmMock.getHypervisorType()).thenReturn(HypervisorType.XenServer);
        when(_vmMock.getState()).thenReturn(State.Running).thenReturn(State.Running).thenReturn(State.Migrating)
            .thenReturn(State.Migrating);
        when(_vmMock.getHostId()).thenReturn(5L);
        when(_vmInstance.getId()).thenReturn(1L);
        when(_vmInstance.getServiceOfferingId()).thenReturn(2L);
        when(_vmInstance.getInstanceName()).thenReturn("myVm");
        when(_vmInstance.getHostId()).thenReturn(5L);
        when(_vmInstance.getType()).thenReturn(VirtualMachine.Type.User);
        when(_vmInstance.getState()).thenReturn(State.Running).thenReturn(State.Running).thenReturn(State.Migrating)
            .thenReturn(State.Migrating);

        // Mock the work item.
        when(_workDao.persist(any(ItWorkVO.class))).thenReturn(_work);
        when(_workDao.update("1", _work)).thenReturn(true);
        when(_work.getId()).thenReturn("1");
        doNothing().when(_work).setStep(ItWorkVO.Step.Done);

        // Mock the vm guru and the user vm object that gets returned.
        _vmMgr._vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>>();
        UserVmManagerImpl userVmManager = mock(UserVmManagerImpl.class);
        _vmMgr.registerGuru(VirtualMachine.Type.User, userVmManager);
        when(userVmManager.findById(anyLong())).thenReturn(_vmMock);

        // Mock the iteration over all the volumes of an instance.
        Iterator<VolumeVO> volumeIterator = mock(Iterator.class);
        when(_volsDao.findUsableVolumesForInstance(anyLong())).thenReturn(_rootVols);
        when(_rootVols.iterator()).thenReturn(volumeIterator);
        when(volumeIterator.hasNext()).thenReturn(true, false);
        when(volumeIterator.next()).thenReturn(_volumeMock);

        // Mock the disk offering and pool objects for a volume.
        when(_volumeMock.getDiskOfferingId()).thenReturn(5L);
        when(_volumeMock.getPoolId()).thenReturn(200L);
        when(_diskOfferingDao.findById(anyLong())).thenReturn(_diskOfferingMock);
        when(_storagePoolDao.findById(anyLong())).thenReturn(_srcStoragePoolMock);

        // Mock the volume to pool mapping.
        when(_volumeToPoolMock.get(_volumeMock)).thenReturn(_destStoragePoolMock);
        when(_destStoragePoolMock.getId()).thenReturn(201L);
        when(_srcStoragePoolMock.getId()).thenReturn(200L);
        when(_destStoragePoolMock.isLocal()).thenReturn(false);
        when(_diskOfferingMock.getUseLocalStorage()).thenReturn(false);
        when(_poolHostDao.findByPoolHost(anyLong(), anyLong())).thenReturn(mock(StoragePoolHostVO.class));

        // Mock hypervisor guru.
        HypervisorGuru guruMock = mock(HypervisorGuru.class);
        when(_hvGuruMgr.getGuru(HypervisorType.XenServer)).thenReturn(guruMock);

        when(_srcHostMock.getClusterId()).thenReturn(3L);
        when(_destHostMock.getClusterId()).thenReturn(3L);

        // Mock the commands and answers to the agent.
        PrepareForMigrationAnswer prepAnswerMock = mock(PrepareForMigrationAnswer.class);
        when(prepAnswerMock.getResult()).thenReturn(true);
        when(_agentMgr.send(anyLong(), isA(PrepareForMigrationCommand.class))).thenReturn(prepAnswerMock);

        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
        when(migAnswerMock.getResult()).thenReturn(true);
        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);

        MigrateWithStorageReceiveAnswer migRecAnswerMock = mock(MigrateWithStorageReceiveAnswer.class);
        when(migRecAnswerMock.getResult()).thenReturn(true);
        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageReceiveCommand.class))).thenReturn(migRecAnswerMock);

        MigrateWithStorageSendAnswer migSendAnswerMock = mock(MigrateWithStorageSendAnswer.class);
        when(migSendAnswerMock.getResult()).thenReturn(true);
        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageSendCommand.class))).thenReturn(migSendAnswerMock);

        MigrateWithStorageCompleteAnswer migCompleteAnswerMock = mock(MigrateWithStorageCompleteAnswer.class);
        when(migCompleteAnswerMock.getResult()).thenReturn(true);
        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageCompleteCommand.class))).thenReturn(migCompleteAnswerMock);

        CheckVirtualMachineAnswer checkVmAnswerMock = mock(CheckVirtualMachineAnswer.class);
        when(checkVmAnswerMock.getResult()).thenReturn(true);
        when(checkVmAnswerMock.getState()).thenReturn(State.Running);
        when(_agentMgr.send(anyLong(), isA(CheckVirtualMachineCommand.class))).thenReturn(checkVmAnswerMock);

        // Mock the state transitions of vm.
        Pair<Long, Long> opaqueMock = new Pair<Long, Long> (_vmMock.getHostId(), _destHostMock.getId());
        when(_vmSnapshotMgr.hasActiveVMSnapshotTasks(anyLong())).thenReturn(false);
        when(_vmInstanceDao.updateState(State.Running, Event.MigrationRequested, State.Migrating, _vmMock, opaqueMock))
            .thenReturn(true);
        when(_vmInstanceDao.updateState(State.Migrating, Event.OperationSucceeded, State.Running, _vmMock, opaqueMock))
            .thenReturn(true);
    }

    // Check migration of a vm with its volumes within a cluster.
    @Test
    public void testMigrateWithVolumeWithinCluster() throws ResourceUnavailableException, ConcurrentOperationException,
        ManagementServerException, VirtualMachineMigrationException, OperationTimedoutException {

        initializeMockConfigForMigratingVmWithVolumes();
        when(_srcHostMock.getClusterId()).thenReturn(3L);
        when(_destHostMock.getClusterId()).thenReturn(3L);

        _vmMgr.migrateWithStorage(_vmInstance, _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
    }

    // Check migration of a vm with its volumes across a cluster.
    @Test
    public void testMigrateWithVolumeAcrossCluster() throws ResourceUnavailableException, ConcurrentOperationException,
        ManagementServerException, VirtualMachineMigrationException, OperationTimedoutException {

        initializeMockConfigForMigratingVmWithVolumes();
        when(_srcHostMock.getClusterId()).thenReturn(3L);
        when(_destHostMock.getClusterId()).thenReturn(4L);

        _vmMgr.migrateWithStorage(_vmInstance, _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
    }

    // Check migration of a vm fails when src and destination pool are not of same type; that is, one is shared and
    // other is local.
    @Test(expected=CloudRuntimeException.class)
    public void testMigrateWithVolumeFail1() throws ResourceUnavailableException, ConcurrentOperationException,
        ManagementServerException, VirtualMachineMigrationException, OperationTimedoutException {

        initializeMockConfigForMigratingVmWithVolumes();
        when(_srcHostMock.getClusterId()).thenReturn(3L);
        when(_destHostMock.getClusterId()).thenReturn(3L);

        when(_destStoragePoolMock.isLocal()).thenReturn(true);
        when(_diskOfferingMock.getUseLocalStorage()).thenReturn(false);

        _vmMgr.migrateWithStorage(_vmInstance, _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
    }

    // Check migration of a vm fails when vm is not in Running state.
    @Test(expected=ConcurrentOperationException.class)
    public void testMigrateWithVolumeFail2() throws ResourceUnavailableException, ConcurrentOperationException,
        ManagementServerException, VirtualMachineMigrationException, OperationTimedoutException {

        initializeMockConfigForMigratingVmWithVolumes();
        when(_srcHostMock.getClusterId()).thenReturn(3L);
        when(_destHostMock.getClusterId()).thenReturn(3L);

        when(_vmMock.getState()).thenReturn(State.Stopped);

        _vmMgr.migrateWithStorage(_vmInstance, _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
    }
}
