// 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.backup.dao.BackupOfferingDao;
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);
        }

        @Bean
        public BackupOfferingDao backupOfferingDao() {
            return Mockito.mock(BackupOfferingDao.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);
            }
        }
    }
}
