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


import com.cloud.agent.AgentManager;
import com.cloud.api.query.dao.SnapshotJoinDao;
import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.Status;
import com.cloud.host.DetailVO;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.projects.ProjectManager;
import com.cloud.resourcelimit.CheckedReservation;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.TemplateProfile;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.LaunchPermissionDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.UserData;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.uservm.UserVm;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VmIsoMapVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.dao.VmIsoMapDao;

import junit.framework.TestCase;

import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.api.command.user.template.RegisterVnfTemplateCmd;
import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
import org.apache.cloudstack.api.command.user.template.UpdateVnfTemplateCmd;
import org.apache.cloudstack.api.command.user.userdata.LinkUserDataToTemplateCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.reservation.dao.ReservationDao;
import org.apache.cloudstack.secstorage.dao.SecondaryStorageHeuristicDao;
import org.apache.cloudstack.secstorage.heuristics.HeuristicType;
import org.apache.cloudstack.snapshot.SnapshotHelper;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.heuristics.HeuristicRuleHelper;
import org.apache.cloudstack.storage.template.VnfTemplateManager;
import org.apache.cloudstack.test.utils.SpringUtils;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class TemplateManagerImplTest extends TestCase {

    @Spy
    @InjectMocks
    TemplateManagerImpl templateManager;

    @Mock
    DataStoreManager dataStoreManager;

    @Mock
    VMTemplateDao vmTemplateDao;

    @Mock
    VMTemplatePoolDao vmTemplatePoolDao;

    @Mock
    TemplateDataStoreDao templateDataStoreDao;

    @Mock
    StoragePoolHostDao storagePoolHostDao;

    @Mock
    PrimaryDataStoreDao primaryDataStoreDao;

    @Mock
    ResourceLimitService resourceLimitMgr;

    @Mock
    ImageStoreDao imgStoreDao;

    @Mock
    GuestOSDao guestOSDao;

    @Mock
    SnapshotDao snapshotDao;

    @Mock
    VolumeDao volumeDao;

    @Mock
    VMTemplateDetailsDao tmpltDetailsDao;

    @Mock
    StorageStrategyFactory storageStrategyFactory;

    @Mock
    VMInstanceDao _vmInstanceDao;

    @Mock
    ReservationDao reservationDao;

    @Mock
    HypervisorGuruManager _hvGuruMgr;

    @Mock
    AccountManager _accountMgr;

    @Mock
    VnfTemplateManager vnfTemplateManager;
    @Mock
    SnapshotJoinDao snapshotJoinDao;
    @Mock
    TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;

    @Mock
    HeuristicRuleHelper heuristicRuleHelperMock;

    @Mock
    UserVmDao _userVmDao;

    @Mock
    VmIsoMapDao _vmIsoMapDao;

    @Mock
    HostDao _hostDao;

    @Mock
    HostDetailsDao _hostDetailsDao;

    @Mock
    UserVmJoinDao _userVmJoinDao;

    public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
        AtomicInteger ai = new AtomicInteger(0);
        public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                        BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        }

        @Override
        protected void beforeExecute(Thread t, Runnable r) {
            ai.addAndGet(1);
        }

        public int getCount() {
            try {
                // Wait for some time to give before execute to run. Otherwise the tests that
                // assert and check that template seeding has been scheduled may fail. If tests
                // are seen to fail, consider increasing the sleep time.
                Thread.sleep(1000);
                return ai.get();
            } catch (Exception e) {
                return -1;
            }
        }
    }

    @Before
    public void setUp() {
        AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.Type.NORMAL, "uuid");
        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
        CallContext.register(user, account);
    }

    @After
    public void tearDown() {
        CallContext.unregister();
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testVerifyTemplateIdOfSystemTemplate() {
        templateManager.verifyTemplateId(1L);
    }

    public void testVerifyTemplateIdOfNonSystemTemplate() {
        templateManager.verifyTemplateId(1L);
    }

    @Test
    public void testForceDeleteTemplate() {
        //In this Unit test all the conditions related to "force template delete flag" are tested.

        DeleteTemplateCmd cmd = mock(DeleteTemplateCmd.class);
        VMTemplateVO template = mock(VMTemplateVO.class);
        TemplateAdapter templateAdapter = mock(TemplateAdapter.class);
        TemplateProfile templateProfile = mock(TemplateProfile.class);


        List<VMInstanceVO> vmInstanceVOList  = new ArrayList<VMInstanceVO>();
        List<TemplateAdapter> adapters  = new ArrayList<TemplateAdapter>();
        adapters.add(templateAdapter);
        when(cmd.getId()).thenReturn(0L);
        when(vmTemplateDao.findById(cmd.getId())).thenReturn(template);
        when(cmd.getZoneId()).thenReturn(null);

        when(template.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.None);
        when(template.getFormat()).thenReturn(Storage.ImageFormat.VMDK);
        templateManager.setTemplateAdapters(adapters);
        when(templateAdapter.getName()).thenReturn(TemplateAdapter.TemplateAdapterType.Hypervisor.getName().toString());
        when(templateAdapter.prepareDelete(any(DeleteTemplateCmd.class))).thenReturn(templateProfile);
        when(templateAdapter.delete(templateProfile)).thenReturn(true);

        //case 1: When Force delete flag is 'true' but VM instance VO list is empty.
        when(cmd.isForced()).thenReturn(true);
        templateManager.deleteTemplate(cmd);

        //case 2.1: When Force delete flag is 'false' and VM instance VO list is empty.
        when(cmd.isForced()).thenReturn(false);
        templateManager.deleteTemplate(cmd);

        //case 2.2: When Force delete flag is 'false' and VM instance VO list is non empty.
        when(cmd.isForced()).thenReturn(false);
        VMInstanceVO vmInstanceVO = mock(VMInstanceVO.class);
        vmInstanceVOList.add(vmInstanceVO);
        when(_vmInstanceDao.listNonExpungedByTemplate(anyLong())).thenReturn(vmInstanceVOList);
        try {
            templateManager.deleteTemplate(cmd);
        } catch(Exception e) {
            assertTrue("Invalid Parameter Value Exception is expected", (e instanceof InvalidParameterValueException));
        }
    }
    @Test
    public void testPrepareTemplateIsSeeded() {
        VMTemplateVO mockTemplate = mock(VMTemplateVO.class);
        when(mockTemplate.getId()).thenReturn(202l);

        StoragePoolVO mockPool = mock(StoragePoolVO.class);

        PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
        when(mockPrimaryDataStore.getId()).thenReturn(2l);

        VMTemplateStoragePoolVO mockTemplateStore = mock(VMTemplateStoragePoolVO.class);
        when(mockTemplateStore.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);

        when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);

        doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());

        VMTemplateStoragePoolVO returnObject = templateManager.prepareTemplateForCreate(mockTemplate, (StoragePool) mockPrimaryDataStore);
        assertTrue("Test template is already seeded", returnObject == mockTemplateStore);
    }

    @Test
    public void testPrepareTemplateNotDownloaded() {
        VMTemplateVO mockTemplate = mock(VMTemplateVO.class);
        when(mockTemplate.getId()).thenReturn(202l);

        StoragePoolVO mockPool = mock(StoragePoolVO.class);

        PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
        when(mockPrimaryDataStore.getId()).thenReturn(2l);
        when(mockPrimaryDataStore.getDataCenterId()).thenReturn(1l);

        when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(null);
        when(templateDataStoreDao.findByTemplateZoneDownloadStatus(202l, 1l, VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).thenReturn(null);

        VMTemplateStoragePoolVO returnObject = templateManager.prepareTemplateForCreate(mockTemplate, (StoragePool) mockPrimaryDataStore);
        assertTrue("Test template is not ready", returnObject == null);
    }

    @Test(expected = CloudRuntimeException.class)
    public void testPrepareTemplateNoHostConnectedToPool() {
        VMTemplateVO mockTemplate = mock(VMTemplateVO.class);
        when(mockTemplate.getId()).thenReturn(202l);

        StoragePoolVO mockPool = mock(StoragePoolVO.class);

        PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
        when(mockPrimaryDataStore.getId()).thenReturn(2l);
        when(mockPrimaryDataStore.getDataCenterId()).thenReturn(1l);

        TemplateDataStoreVO mockTemplateDataStore = mock(TemplateDataStoreVO.class);

        when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(null);
        when(templateDataStoreDao.findByTemplateZoneDownloadStatus(202l, 1l, VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).thenReturn(mockTemplateDataStore);
        when(storagePoolHostDao.listByHostStatus(2l, Status.Up)).thenReturn(null);

        templateManager.prepareTemplateForCreate(mockTemplate, (StoragePool) mockPrimaryDataStore);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testPrepareTemplateInvalidTemplate() {
        when(vmTemplateDao.findById(anyLong())).thenReturn(null);
        templateManager.prepareTemplate(202, 1, null);
    }

    @Test
    public void testTemplateScheduledForDownloadInOnePool() {
        VMTemplateVO mockTemplate = mock(VMTemplateVO.class);
        StoragePoolVO mockPool = mock(StoragePoolVO.class);
        PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
        VMTemplateStoragePoolVO mockTemplateStore = mock(VMTemplateStoragePoolVO.class);

        when(mockPrimaryDataStore.getId()).thenReturn(2l);
        when(mockPool.getId()).thenReturn(2l);
        when(mockPool.getStatus()).thenReturn(StoragePoolStatus.Up);
        when(mockPool.getDataCenterId()).thenReturn(1l);
        when(mockTemplate.getId()).thenReturn(202l);
        when(mockTemplateStore.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
        when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
        when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
        when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
        when(primaryDataStoreDao.findById(anyLong())).thenReturn(mockPool);

        doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());

        ExecutorService preloadExecutor = new CustomThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),
                new NamedThreadFactory("Template-Preloader"));
        templateManager._preloadExecutor = preloadExecutor;

        templateManager.prepareTemplate(202, 1, 2l);
        assertTrue("Test template is scheduled for seeding to on pool", ((CustomThreadPoolExecutor)preloadExecutor).getCount() == 1);
    }

    @Test
    public void testTemplateScheduledForDownloadInDisabledPool() {
        VMTemplateVO mockTemplate = mock(VMTemplateVO.class);
        StoragePoolVO mockPool = mock(StoragePoolVO.class);
        PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
        VMTemplateStoragePoolVO mockTemplateStore = mock(VMTemplateStoragePoolVO.class);

        when(mockPool.getStatus()).thenReturn(StoragePoolStatus.Disabled);
        when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
        when(primaryDataStoreDao.findById(anyLong())).thenReturn(mockPool);

        ExecutorService preloadExecutor = new CustomThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),
                new NamedThreadFactory("Template-Preloader"));
        templateManager._preloadExecutor = preloadExecutor;

        templateManager.prepareTemplate(202, 1, 2l);
        assertTrue("Test template is not scheduled for seeding on disabled pool", ((CustomThreadPoolExecutor)preloadExecutor).getCount() == 0);
    }

    @Test
    public void testTemplateScheduledForDownloadInMultiplePool() {
        VMTemplateVO mockTemplate = mock(VMTemplateVO.class);
        PrimaryDataStore mockPrimaryDataStore = mock(PrimaryDataStore.class);
        VMTemplateStoragePoolVO mockTemplateStore = mock(VMTemplateStoragePoolVO.class);
        List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();

        StoragePoolVO mockPool1 = mock(StoragePoolVO.class);
        when(mockPool1.getId()).thenReturn(2l);
        when(mockPool1.getDataCenterId()).thenReturn(1l);
        StoragePoolVO mockPool2 = mock(StoragePoolVO.class);
        when(mockPool2.getDataCenterId()).thenReturn(1l);
        StoragePoolVO mockPool3 = mock(StoragePoolVO.class);
        when(mockPool3.getDataCenterId()).thenReturn(2l);
        pools.add(mockPool1);
        pools.add(mockPool2);
        pools.add(mockPool3);

        when(mockPrimaryDataStore.getId()).thenReturn(2l);
        when(mockTemplate.getId()).thenReturn(202l);
        when(mockTemplateStore.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
        when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
        when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
        when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
        when(primaryDataStoreDao.listByStatus(StoragePoolStatus.Up)).thenReturn(pools);

        doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());

        ExecutorService preloadExecutor = new CustomThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),
                new NamedThreadFactory("Template-Preloader"));
        templateManager._preloadExecutor = preloadExecutor;

        templateManager.prepareTemplate(202, 1, null);
        assertTrue("Test template is scheduled for seeding to on pool", ((CustomThreadPoolExecutor) preloadExecutor).getCount() == 2);
    }

    @Test
    public void testCreatePrivateTemplateRecordForRegionStore() throws ResourceAllocationException {

        CreateTemplateCmd mockCreateCmd = mock(CreateTemplateCmd.class);
        when(mockCreateCmd.getTemplateName()).thenReturn("test");
        when(mockCreateCmd.getTemplateTag()).thenReturn(null);
        when(mockCreateCmd.getBits()).thenReturn(64);
        when(mockCreateCmd.getRequiresHvm()).thenReturn(true);
        when(mockCreateCmd.isPasswordEnabled()).thenReturn(false);
        when(mockCreateCmd.isPublic()).thenReturn(false);
        when(mockCreateCmd.isFeatured()).thenReturn(false);
        when(mockCreateCmd.isDynamicallyScalable()).thenReturn(false);
        when(mockCreateCmd.getVolumeId()).thenReturn(null);
        when(mockCreateCmd.getSnapshotId()).thenReturn(1L);
        when(mockCreateCmd.getOsTypeId()).thenReturn(1L);
        when(mockCreateCmd.getDetails()).thenReturn(null);
        when(mockCreateCmd.getZoneId()).thenReturn(null);

        Account mockTemplateOwner = mock(Account.class);

        SnapshotVO mockSnapshot = mock(SnapshotVO.class);
        when(snapshotDao.findById(anyLong())).thenReturn(mockSnapshot);

        when(mockSnapshot.getVolumeId()).thenReturn(1L);
        when(mockSnapshot.getState()).thenReturn(Snapshot.State.BackedUp);
        when(mockSnapshot.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);

        GuestOSVO mockGuestOS = mock(GuestOSVO.class);
        when(guestOSDao.findById(anyLong())).thenReturn(mockGuestOS);

        when(vmTemplateDao.getNextInSequence(eq(Long.class), eq("id"))).thenReturn(1L);

        List<ImageStoreVO> mockRegionStores = new ArrayList<>();
        ImageStoreVO mockRegionStore = mock(ImageStoreVO.class);
        mockRegionStores.add(mockRegionStore);
        when(imgStoreDao.findRegionImageStores()).thenReturn(mockRegionStores);

        when(vmTemplateDao.persist(any(VMTemplateVO.class))).thenAnswer(new Answer<VMTemplateVO>() {
            @Override
            public VMTemplateVO answer(InvocationOnMock invocationOnMock) throws Throwable {
                Object[] args = invocationOnMock.getArguments();
                return (VMTemplateVO)args[0];
            }
        });

        try (MockedConstruction<CheckedReservation> mockCheckedReservation = Mockito.mockConstruction(CheckedReservation.class)) {
            VMTemplateVO template = templateManager.createPrivateTemplateRecord(mockCreateCmd, mockTemplateOwner);
            assertTrue("Template in a region store should have cross zones set", template.isCrossZones());
        }
    }

    @Test
    public void testLinkUserDataToTemplate() {
        LinkUserDataToTemplateCmd cmd = Mockito.mock(LinkUserDataToTemplateCmd.class);
        when(cmd.getTemplateId()).thenReturn(1L);
        when(cmd.getIsoId()).thenReturn(null);
        when(cmd.getUserdataId()).thenReturn(2L);
        when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);

        VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
        when(vmTemplateDao.findById(anyLong())).thenReturn(template);

        VirtualMachineTemplate resultTemplate = templateManager.linkUserDataToTemplate(cmd);

        Assert.assertEquals(template, resultTemplate);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testLinkUserDataToTemplateByProvidingBothISOAndTemplateId() {
        LinkUserDataToTemplateCmd cmd = Mockito.mock(LinkUserDataToTemplateCmd.class);
        when(cmd.getTemplateId()).thenReturn(1L);
        when(cmd.getIsoId()).thenReturn(1L);
        when(cmd.getUserdataId()).thenReturn(2L);
        when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);

        VMTemplateVO template = Mockito.mock(VMTemplateVO.class);

        templateManager.linkUserDataToTemplate(cmd);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testLinkUserDataToTemplateByNotProvidingBothISOAndTemplateId() {
        LinkUserDataToTemplateCmd cmd = Mockito.mock(LinkUserDataToTemplateCmd.class);
        when(cmd.getTemplateId()).thenReturn(null);
        when(cmd.getIsoId()).thenReturn(null);
        when(cmd.getUserdataId()).thenReturn(2L);
        when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);

        VMTemplateVO template = Mockito.mock(VMTemplateVO.class);

        templateManager.linkUserDataToTemplate(cmd);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testLinkUserDataToTemplateWhenNoTemplate() {
        LinkUserDataToTemplateCmd cmd = Mockito.mock(LinkUserDataToTemplateCmd.class);
        when(cmd.getTemplateId()).thenReturn(1L);
        when(cmd.getIsoId()).thenReturn(null);
        when(cmd.getUserdataId()).thenReturn(2L);
        when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);

        when(vmTemplateDao.findById(anyLong())).thenReturn(null);

        templateManager.linkUserDataToTemplate(cmd);
    }

    @Test
    public void testUnLinkUserDataToTemplate() {
        LinkUserDataToTemplateCmd cmd = Mockito.mock(LinkUserDataToTemplateCmd.class);
        when(cmd.getTemplateId()).thenReturn(1L);
        when(cmd.getIsoId()).thenReturn(null);
        when(cmd.getUserdataId()).thenReturn(null);
        when(cmd.getUserdataPolicy()).thenReturn(UserData.UserDataOverridePolicy.ALLOWOVERRIDE);

        VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
        when(template.getId()).thenReturn(1L);
        when(vmTemplateDao.findById(1L)).thenReturn(template);

        VirtualMachineTemplate resultTemplate = templateManager.linkUserDataToTemplate(cmd);

        Assert.assertEquals(template, resultTemplate);
    }

    @Test
    public void getImageStoreTestStoreUuidIsNotNullShouldReturnAValidImageStoreIfValidUuid() {
        DataStore dataStore = Mockito.mock(DataStore.class);
        VolumeVO volumeVO = Mockito.mock(VolumeVO.class);

        Mockito.when(dataStoreManager.getDataStore(Mockito.anyString(), Mockito.any(DataStoreRole.class))).thenReturn(dataStore);

        templateManager.getImageStore("UUID", 1L, volumeVO);
    }

    @Test(expected = CloudRuntimeException.class)
    public void getImageStoreTestStoreUuidIsNotNullShouldThrowCloudRuntimeExceptionIfInvalidUuid() {
        VolumeVO volumeVO = Mockito.mock(VolumeVO.class);

        Mockito.when(dataStoreManager.getDataStore(Mockito.anyString(), Mockito.any(DataStoreRole.class))).thenReturn(null);

        templateManager.getImageStore("UUID", 1L, volumeVO);
    }

    @Test
    public void getImageStoreTestStoreUuidIsNullAndThereIsNoActiveHeuristicRulesShouldCallGetImageStoreWithFreeCapacity() {
        DataStore dataStore = Mockito.mock(DataStore.class);
        VolumeVO volumeVO = Mockito.mock(VolumeVO.class);

        Mockito.when(heuristicRuleHelperMock.getImageStoreIfThereIsHeuristicRule(Mockito.anyLong(), Mockito.any(HeuristicType.class), Mockito.any(VolumeVO.class))).thenReturn(null);
        Mockito.when(dataStoreManager.getImageStoreWithFreeCapacity(Mockito.anyLong())).thenReturn(dataStore);

        templateManager.getImageStore(null, 1L, volumeVO);
        Mockito.verify(dataStoreManager, Mockito.times(1)).getImageStoreWithFreeCapacity(Mockito.anyLong());
    }

    @Test
    public void getImageStoreTestStoreUuidIsNullAndThereIsActiveHeuristicRulesShouldNotCallGetImageStoreWithFreeCapacity() {
        DataStore dataStore = Mockito.mock(DataStore.class);
        VolumeVO volumeVO = Mockito.mock(VolumeVO.class);

        Mockito.when(heuristicRuleHelperMock.getImageStoreIfThereIsHeuristicRule(Mockito.anyLong(), Mockito.any(HeuristicType.class), Mockito.any(VolumeVO.class))).thenReturn(dataStore);

        templateManager.getImageStore(null, 1L, volumeVO);
        Mockito.verify(dataStoreManager, Mockito.times(0)).getImageStoreWithFreeCapacity(Mockito.anyLong());
    }

    @Test
    public void testRegisterTemplateWithTemplateType() {
        RegisterTemplateCmd cmd = Mockito.mock(RegisterTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
        Assert.assertEquals(Storage.TemplateType.SYSTEM, type);
    }

    @Test
    public void testRegisterTemplateWithoutTemplateType() {
        RegisterTemplateCmd cmd = Mockito.mock(RegisterTemplateCmd.class);
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
        Assert.assertEquals(Storage.TemplateType.USER, type);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testRegisterTemplateWithSystemTemplateTypeByUser() {
        RegisterVnfTemplateCmd cmd = Mockito.mock(RegisterVnfTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testRegisterVnfTemplateWithTemplateType() {
        RegisterVnfTemplateCmd cmd = Mockito.mock(RegisterVnfTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
        Assert.assertEquals(Storage.TemplateType.VNF, type);
    }

    @Test
    public void testRegisterVnfTemplateWithoutTemplateType() {
        RegisterVnfTemplateCmd cmd = Mockito.mock(RegisterVnfTemplateCmd.class);
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
        Assert.assertEquals(Storage.TemplateType.VNF, type);
    }

    @Test
    public void testUpdateTemplateWithTemplateType() {
        UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.XenServer);
        Assert.assertEquals(Storage.TemplateType.SYSTEM, type);
    }

    @Test
    public void testUpdateTemplateWithoutTemplateType() {
        UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
        Assert.assertNull(type);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testUpdateTemplateWithInvalidTemplateType() {
        UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn("invalidtype");
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.VMware);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testUpdateTemplateWithInvalidTemplateTypeForRouting() {
        UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.USER.toString());
        when(cmd.isRoutingType()).thenReturn(true);
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testUpdateTemplateWithInvalidCrossZonesForSystem() {
        UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, false, Hypervisor.HypervisorType.KVM);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testUpdateTemplateWithSystemTemplateTypeByUser() {
        UpdateVnfTemplateCmd cmd = Mockito.mock(UpdateVnfTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.XenServer);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void testUpdateVnfTemplateWithTemplateType() {
        UpdateVnfTemplateCmd cmd = Mockito.mock(UpdateVnfTemplateCmd.class);
        when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
        Assert.assertEquals(Storage.TemplateType.VNF, type);
    }

    @Test
    public void testUpdateVnfTemplateWithoutTemplateType() {
        UpdateVnfTemplateCmd cmd = Mockito.mock(UpdateVnfTemplateCmd.class);
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
        Assert.assertNull(type);
    }

    @Test
    public void testDeleteTemplateWithTemplateType() {
        DeleteTemplateCmd cmd = new DeleteTemplateCmd();
        Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.VMware);
        Assert.assertNull(type);
    }

    @Test
    public void verifyHeuristicRulesForZoneTestTemplateIsISOFormatShouldCheckForISOHeuristicType() {
        VMTemplateVO vmTemplateVOMock = Mockito.mock(VMTemplateVO.class);

        Mockito.when(vmTemplateVOMock.getFormat()).thenReturn(Storage.ImageFormat.ISO);
        templateManager.verifyHeuristicRulesForZone(vmTemplateVOMock, 1L);

        Mockito.verify(heuristicRuleHelperMock, Mockito.times(1)).getImageStoreIfThereIsHeuristicRule(1L, HeuristicType.ISO, vmTemplateVOMock);
    }

    @Test
    public void verifyHeuristicRulesForZoneTestTemplateNotISOFormatShouldCheckForTemplateHeuristicType() {
        VMTemplateVO vmTemplateVOMock = Mockito.mock(VMTemplateVO.class);

        Mockito.when(vmTemplateVOMock.getFormat()).thenReturn(Storage.ImageFormat.QCOW2);
        templateManager.verifyHeuristicRulesForZone(vmTemplateVOMock, 1L);

        Mockito.verify(heuristicRuleHelperMock, Mockito.times(1)).getImageStoreIfThereIsHeuristicRule(1L, HeuristicType.TEMPLATE, vmTemplateVOMock);
    }

    @Test
    public void highestCdromMapEntryReturnsNullWhenMapIsEmpty() {
        Mockito.when(_vmIsoMapDao.listByVmId(1L)).thenReturn(new ArrayList<>());
        Assert.assertNull(templateManager.highestCdromMapEntry(1L));
    }

    @Test
    public void highestCdromMapEntryReturnsEntryWithMaxDeviceSeq() {
        VmIsoMapVO low = new VmIsoMapVO(1L, 100L, 4);
        VmIsoMapVO high = new VmIsoMapVO(1L, 200L, 5);
        Mockito.when(_vmIsoMapDao.listByVmId(1L)).thenReturn(Arrays.asList(low, high));
        VmIsoMapVO result = templateManager.highestCdromMapEntry(1L);
        Assert.assertNotNull(result);
        Assert.assertEquals(5, result.getDeviceSeq());
    }

    @Test
    public void attachISOToVMAttachWritesToIsoIdWhenPrimarySlotEmpty() {
        UserVmVO vm = Mockito.mock(UserVmVO.class);
        VMTemplateVO iso = Mockito.mock(VMTemplateVO.class);
        Mockito.when(_userVmDao.findById(1L)).thenReturn(vm);
        Mockito.when(vmTemplateDao.findById(42L)).thenReturn(iso);
        Mockito.when(iso.getId()).thenReturn(42L);
        Mockito.when(vm.getIsoId()).thenReturn(null);

        boolean result = templateManager.attachISOToVM(1L, 1L, 42L, true, false, false);

        Assert.assertTrue(result);
        Mockito.verify(vm).setIsoId(42L);
        Mockito.verify(_userVmDao).update(eq(1L), eq(vm));
        Mockito.verify(_vmIsoMapDao, Mockito.never()).persist(any(VmIsoMapVO.class));
    }

    @Test
    public void resolveIsoIdForDetachReturnsPrimaryWhenOnlyPrimaryIsAttached() {
        Long resolved = templateManager.resolveIsoIdForDetach(99L, new ArrayList<>(), null);
        Assert.assertEquals(Long.valueOf(99L), resolved);
    }

    @Test
    public void resolveIsoIdForDetachReturnsMapEntryWhenOnlyMapHasOne() {
        VmIsoMapVO row = new VmIsoMapVO(1L, 100L, 4);
        Long resolved = templateManager.resolveIsoIdForDetach(null, Arrays.asList(row), null);
        Assert.assertEquals(Long.valueOf(100L), resolved);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void resolveIsoIdForDetachThrowsWhenMultipleAttachedAndNoIdGiven() {
        VmIsoMapVO row = new VmIsoMapVO(1L, 100L, 4);
        templateManager.resolveIsoIdForDetach(99L, Arrays.asList(row), null);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void resolveIsoIdForDetachThrowsWhenNothingAttached() {
        templateManager.resolveIsoIdForDetach(null, new ArrayList<>(), null);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void resolveIsoIdForDetachThrowsWhenIdNotAttached() {
        templateManager.resolveIsoIdForDetach(99L, new ArrayList<>(), 42L);
    }

    @Test
    public void isIsoAlreadyAttachedReturnsTrueWhenPrimaryMatches() {
        Assert.assertTrue(templateManager.isIsoAlreadyAttached(1L, 42L, 42L));
    }

    @Test
    public void isIsoAlreadyAttachedReturnsTrueWhenInMap() {
        Mockito.when(_vmIsoMapDao.findByVmIdIsoId(1L, 42L)).thenReturn(new VmIsoMapVO(1L, 42L, 4));
        Assert.assertTrue(templateManager.isIsoAlreadyAttached(1L, 99L, 42L));
    }

    @Test
    public void isIsoAlreadyAttachedReturnsFalseWhenNotAttached() {
        Mockito.when(_vmIsoMapDao.findByVmIdIsoId(1L, 42L)).thenReturn(null);
        Assert.assertFalse(templateManager.isIsoAlreadyAttached(1L, null, 42L));
    }

    @Test
    public void attachISOToVMAttachWritesToVmIsoMapWhenPrimarySlotOccupied() {
        UserVmVO vm = Mockito.mock(UserVmVO.class);
        VMTemplateVO iso = Mockito.mock(VMTemplateVO.class);
        Mockito.when(_userVmDao.findById(1L)).thenReturn(vm);
        Mockito.when(vmTemplateDao.findById(42L)).thenReturn(iso);
        Mockito.when(iso.getId()).thenReturn(42L);
        Mockito.when(vm.getIsoId()).thenReturn(99L);
        Mockito.when(_vmIsoMapDao.listByVmId(1L)).thenReturn(new ArrayList<>());

        boolean result = templateManager.attachISOToVM(1L, 1L, 42L, true, false, false);

        Assert.assertTrue(result);
        Mockito.verify(_vmIsoMapDao).persist(Mockito.argThat(row ->
                row.getVmId() == 1L && row.getIsoId() == 42L
                        && row.getDeviceSeq() == TemplateManager.CDROM_PRIMARY_DEVICE_SEQ + 1));
        Mockito.verify(vm, Mockito.never()).setIsoId(anyLong());
    }

    @Test(expected = InvalidParameterValueException.class)
    public void enforceCdromAttachLimitsThrowsWhenIsoAlreadyAttachedAtPrimary() {
        UserVm vm = Mockito.mock(UserVm.class);
        Mockito.when(vm.getIsoId()).thenReturn(42L);
        templateManager.enforceCdromAttachLimits(1L, vm, 42L);
    }

    @Test(expected = InvalidParameterValueException.class)
    public void enforceCdromAttachLimitsThrowsWhenIsoAlreadyAttachedInMap() {
        UserVm vm = Mockito.mock(UserVm.class);
        Mockito.when(vm.getIsoId()).thenReturn(99L);
        Mockito.when(_vmIsoMapDao.findByVmIdIsoId(1L, 42L)).thenReturn(new VmIsoMapVO(1L, 42L, 4));
        templateManager.enforceCdromAttachLimits(1L, vm, 42L);
    }

    @Test
    public void advertisedCdromCapReturnsDefaultWhenHostIdNull() {
        Assert.assertEquals(TemplateManager.DEFAULT_CDROM_MAX_PER_VM, templateManager.advertisedCdromCap(null));
    }

    @Test
    public void advertisedCdromCapReturnsDefaultWhenDetailMissing() {
        Mockito.when(_hostDetailsDao.findDetail(7L, Host.HOST_CDROM_MAX_COUNT)).thenReturn(null);
        Assert.assertEquals(TemplateManager.DEFAULT_CDROM_MAX_PER_VM, templateManager.advertisedCdromCap(7L));
    }

    @Test
    public void advertisedCdromCapReturnsParsedValue() {
        DetailVO detail = Mockito.mock(DetailVO.class);
        Mockito.when(detail.getValue()).thenReturn("3");
        Mockito.when(_hostDetailsDao.findDetail(7L, Host.HOST_CDROM_MAX_COUNT)).thenReturn(detail);
        Assert.assertEquals(3, templateManager.advertisedCdromCap(7L));
    }

    @Test
    public void advertisedCdromCapFallsBackOnInvalidValue() {
        DetailVO detail = Mockito.mock(DetailVO.class);
        Mockito.when(detail.getValue()).thenReturn("not-a-number");
        Mockito.when(_hostDetailsDao.findDetail(7L, Host.HOST_CDROM_MAX_COUNT)).thenReturn(detail);
        Assert.assertEquals(TemplateManager.DEFAULT_CDROM_MAX_PER_VM, templateManager.advertisedCdromCap(7L));
    }

    @Test
    public void hostIdForVmReturnsCurrentHost() {
        VirtualMachine vm = Mockito.mock(VirtualMachine.class);
        Mockito.when(vm.getHostId()).thenReturn(42L);
        Assert.assertEquals(Long.valueOf(42L), templateManager.hostIdForVm(vm));
    }

    @Test
    public void hostIdForVmFallsBackToLastHost() {
        VirtualMachine vm = Mockito.mock(VirtualMachine.class);
        Mockito.when(vm.getHostId()).thenReturn(null);
        Mockito.when(vm.getLastHostId()).thenReturn(99L);
        Assert.assertEquals(Long.valueOf(99L), templateManager.hostIdForVm(vm));
    }

    @Test
    public void hostIdForVmReturnsNullWhenNoHost() {
        VirtualMachine vm = Mockito.mock(VirtualMachine.class);
        Mockito.when(vm.getHostId()).thenReturn(null);
        Mockito.when(vm.getLastHostId()).thenReturn(null);
        Assert.assertNull(templateManager.hostIdForVm(vm));
    }

    @Test
    public void effectiveMaxCdromsReturnsConfiguredCapWhenWithinHypervisorCap() {
        VirtualMachine vm = Mockito.mock(VirtualMachine.class);
        DetailVO detail = Mockito.mock(DetailVO.class);
        Mockito.when(detail.getValue()).thenReturn("2");
        HostVO host = Mockito.mock(HostVO.class);
        Mockito.when(host.getClusterId()).thenReturn(5L);
        Mockito.when(_hostDao.findById(7L)).thenReturn(host);
        Mockito.when(_hostDetailsDao.findDetail(7L, Host.HOST_CDROM_MAX_COUNT)).thenReturn(detail);
        // Configured cap defaults to 1 (no cluster override mocked); hypervisor cap is 2; 1 <= 2 → no throw, returns 1.
        Assert.assertEquals(1, templateManager.effectiveMaxCdroms(vm, 7L));
    }

    @Test
    public void templateIsDeleteableReturnsTrueWhenNoVmsUseIso() {
        Mockito.when(_userVmJoinDao.listActiveByIsoId(42L)).thenReturn(new ArrayList<>());
        Mockito.when(_vmIsoMapDao.listByIsoId(42L)).thenReturn(new ArrayList<>());
        Assert.assertTrue(templateManager.templateIsDeleteable(42L));
    }

    @Test
    public void templateIsDeleteableReturnsFalseWhenPrimarySlotInUse() {
        Mockito.when(_userVmJoinDao.listActiveByIsoId(42L))
                .thenReturn(java.util.Collections.singletonList(Mockito.mock(UserVmJoinVO.class)));
        Assert.assertFalse(templateManager.templateIsDeleteable(42L));
        // Should not even need to consult vm_iso_map once primary slot in use.
        Mockito.verify(_vmIsoMapDao, Mockito.never()).listByIsoId(anyLong());
    }

    @Test
    public void templateIsDeleteableReturnsFalseWhenAttachedViaVmIsoMapToActiveVm() {
        Mockito.when(_userVmJoinDao.listActiveByIsoId(42L)).thenReturn(new ArrayList<>());
        Mockito.when(_vmIsoMapDao.listByIsoId(42L))
                .thenReturn(java.util.Collections.singletonList(new VmIsoMapVO(1L, 42L, 4)));
        UserVmVO vm = Mockito.mock(UserVmVO.class);
        Mockito.when(vm.getState()).thenReturn(State.Running);
        Mockito.when(vm.getUuid()).thenReturn("uuid-1");
        Mockito.when(_userVmDao.findById(1L)).thenReturn(vm);
        Assert.assertFalse(templateManager.templateIsDeleteable(42L));
    }

    @Test
    public void templateIsDeleteableIgnoresVmIsoMapForDestroyedVm() {
        Mockito.when(_userVmJoinDao.listActiveByIsoId(42L)).thenReturn(new ArrayList<>());
        Mockito.when(_vmIsoMapDao.listByIsoId(42L))
                .thenReturn(java.util.Collections.singletonList(new VmIsoMapVO(1L, 42L, 4)));
        UserVmVO vm = Mockito.mock(UserVmVO.class);
        Mockito.when(vm.getState()).thenReturn(State.Expunging);
        Mockito.when(_userVmDao.findById(1L)).thenReturn(vm);
        Assert.assertTrue(templateManager.templateIsDeleteable(42L));
    }


    @Configuration
    @ComponentScan(basePackageClasses = {TemplateManagerImpl.class},
            includeFilters = {@ComponentScan.Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)},
            useDefaultFilters = false)
    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {

        @Bean
        public DataStoreManager dataStoreManager() {
            return Mockito.mock(DataStoreManager.class);
        }

        @Bean
        public VMTemplateDao vmTemplateDao() {
            return Mockito.mock(VMTemplateDao.class);
        }

        @Bean
        public StorageStrategyFactory storageStrategyFactory() {
            return Mockito.mock(StorageStrategyFactory.class);
        }

        @Bean
        public VMTemplatePoolDao vmTemplatePoolDao() {
            return Mockito.mock(VMTemplatePoolDao.class);
        }

        @Bean
        public TemplateDataStoreDao templateDataStoreDao() {
            return Mockito.mock(TemplateDataStoreDao.class);
        }

        @Bean
        public VMTemplateZoneDao vmTemplateZoneDao() {
            return Mockito.mock(VMTemplateZoneDao.class);
        }

        @Bean
        public VMInstanceDao vmInstanceDao() {
            return Mockito.mock(VMInstanceDao.class);
        }

        @Bean
        public PrimaryDataStoreDao primaryDataStoreDao() {
            return Mockito.mock(PrimaryDataStoreDao.class);
        }

        @Bean
        public StoragePoolHostDao storagePoolHostDao() {
            return Mockito.mock(StoragePoolHostDao.class);
        }

        @Bean
        public AccountDao accountDao() {
            return Mockito.mock(AccountDao.class);
        }

        @Bean
        public AgentManager agentMgr() {
            return Mockito.mock(AgentManager.class);
        }

        @Bean
        public AccountManager accountManager() {
            return Mockito.mock(AccountManager.class);
        }

        @Bean
        public HostDao hostDao() {
            return Mockito.mock(HostDao.class);
        }

        @Bean
        public DataCenterDao dcDao() {
            return Mockito.mock(DataCenterDao.class);
        }

        @Bean
        public UserVmDao userVmDao() {
            return Mockito.mock(UserVmDao.class);
        }

        @Bean
        public VolumeDao volumeDao() {
            return Mockito.mock(VolumeDao.class);
        }

        @Bean
        public SnapshotDao snapshotDao() {
            return Mockito.mock(SnapshotDao.class);
        }

        @Bean
        public ConfigurationDao configDao() {
            return Mockito.mock(ConfigurationDao.class);
        }

        @Bean
        public DomainDao domainDao() {
            return Mockito.mock(DomainDao.class);
        }

        @Bean
        public GuestOSDao guestOSDao() {
            return Mockito.mock(GuestOSDao.class);
        }

        @Bean
        public StorageManager storageManager() {
            return Mockito.mock(StorageManager.class);
        }

        @Bean
        public UsageEventDao usageEventDao() {
            return Mockito.mock(UsageEventDao.class);
        }

        @Bean
        public ResourceLimitService resourceLimitMgr() {
            return Mockito.mock(ResourceLimitService.class);
        }

        @Bean
        public LaunchPermissionDao launchPermissionDao() {
            return Mockito.mock(LaunchPermissionDao.class);
        }

        @Bean
        public ProjectManager projectMgr() {
            return Mockito.mock(ProjectManager.class);
        }

        @Bean
        public VolumeDataFactory volFactory() {
            return Mockito.mock(VolumeDataFactory.class);
        }

        @Bean
        public TemplateDataFactory tmplFactory() {
            return Mockito.mock(TemplateDataFactory.class);
        }

        @Bean
        public SnapshotDataFactory snapshotFactory() {
            return Mockito.mock(SnapshotDataFactory.class);
        }

        @Bean
        public TemplateService tmpltSvr() {
            return Mockito.mock(TemplateService.class);
        }

        @Bean
        public VolumeOrchestrationService volumeMgr() {
            return Mockito.mock(VolumeOrchestrationService.class);
        }

        @Bean
        public EndPointSelector epSelector() {
            return Mockito.mock(EndPointSelector.class);
        }

        @Bean
        public UserVmJoinDao userVmJoinDao() {
            return Mockito.mock(UserVmJoinDao.class);
        }

        @Bean
        public SnapshotDataStoreDao snapshotStoreDao() {
            return Mockito.mock(SnapshotDataStoreDao.class);
        }

        @Bean
        public ImageStoreDao imageStoreDao() {
            return Mockito.mock(ImageStoreDao.class);
        }

        @Bean
        public MessageBus messageBus() {
            return Mockito.mock(MessageBus.class);
        }

        @Bean
        public StorageCacheManager cacheMgr() {
            return Mockito.mock(StorageCacheManager.class);
        }

        @Bean
        public TemplateAdapter templateAdapter() {
            return Mockito.mock(TemplateAdapter.class);
        }

        @Bean
        public VMTemplateDetailsDao vmTemplateDetailsDao() {
            return Mockito.mock(VMTemplateDetailsDao.class);
        }

        @Bean
        public HypervisorGuruManager hypervisorGuruManager() {
            return Mockito.mock(HypervisorGuruManager.class);
        }

        @Bean
        public VnfTemplateManager vnfTemplateManager() {
            return Mockito.mock(VnfTemplateManager.class);
        }

        @Bean
        public TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao() {
            return Mockito.mock(TemplateDeployAsIsDetailsDao.class);
        }

        @Bean
        public ReservationDao reservationDao() {
            return Mockito.mock(ReservationDao.class);
        }

        @Bean
        public SnapshotHelper snapshotHelper() {
            return Mockito.mock(SnapshotHelper.class);
        }

        @Bean
        public SnapshotService snapshotService() {
            return Mockito.mock(SnapshotService.class);
        }

        @Bean
        public SecondaryStorageHeuristicDao secondaryStorageHeuristicDao() {
            return Mockito.mock(SecondaryStorageHeuristicDao.class);
        }

        @Bean
        public HeuristicRuleHelper heuristicRuleHelper() {
            return Mockito.mock(HeuristicRuleHelper.class);
        }
        @Bean
        public SnapshotJoinDao snapshotJoinDao() {
            return Mockito.mock(SnapshotJoinDao.class);
        }


        public static class Library implements TypeFilter {
            @Override
            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
            }
        }
    }
}
