// 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 java.net.Inet6Address;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;

import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd;
import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
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.ExtractTemplateCmd;
import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
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.DataStoreRole;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.ComputeChecksumCommand;
import com.cloud.agent.api.DownloadTemplateFromSwiftToSecondaryStorageCommand;
import com.cloud.agent.api.UploadTemplateToSwiftFromSecondaryStorageCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.SwiftTO;

import com.cloud.api.ApiDBUtils;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
import com.cloud.event.UsageEventVO;
import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;

import com.cloud.resource.ResourceManager;
import com.cloud.server.ConfigurationServer;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;

import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.TemplateProfile;
import com.cloud.storage.Upload;
import com.cloud.storage.Upload.Type;

import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateS3VO;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeManager;
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.UploadDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateS3Dao;
import com.cloud.storage.dao.VMTemplateSwiftDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
import com.cloud.storage.s3.S3Manager;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.swift.SwiftManager;
import com.cloud.storage.upload.UploadMonitor;
import com.cloud.template.TemplateAdapter.TemplateAdapterType;

import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountService;
import com.cloud.user.AccountVO;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserAccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.*;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;

@Component
@Local(value={TemplateManager.class, TemplateService.class})
public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateService {
    private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
    @Inject VMTemplateDao _tmpltDao;
    @Inject VMTemplateHostDao _tmpltHostDao;
    @Inject VMTemplatePoolDao _tmpltPoolDao;
    @Inject VMTemplateZoneDao _tmpltZoneDao;
    @Inject
    protected VMTemplateDetailsDao _templateDetailsDao;
    @Inject VMInstanceDao _vmInstanceDao;
    @Inject PrimaryDataStoreDao _poolDao;
    @Inject StoragePoolHostDao _poolHostDao;
    @Inject EventDao _eventDao;
    @Inject DownloadMonitor _downloadMonitor;
    @Inject UploadMonitor _uploadMonitor;
    @Inject UserAccountDao _userAccountDao;
    @Inject AccountDao _accountDao;
    @Inject UserDao _userDao;
    @Inject AgentManager _agentMgr;
    @Inject AccountManager _accountMgr;
    @Inject HostDao _hostDao;
    @Inject DataCenterDao _dcDao;
    @Inject UserVmDao _userVmDao;
    @Inject VolumeDao _volumeDao;
    @Inject SnapshotDao _snapshotDao;
    @Inject
    SwiftManager _swiftMgr;
    @Inject
    S3Manager _s3Mgr;
    @Inject
    VMTemplateSwiftDao _tmpltSwiftDao;
    @Inject
    VMTemplateS3Dao _vmS3TemplateDao;
    @Inject
    ConfigurationDao _configDao;
    @Inject
    ClusterDao _clusterDao;
    @Inject DomainDao _domainDao;
    @Inject UploadDao _uploadDao;
    @Inject
    protected GuestOSDao _guestOSDao;
    long _routerTemplateId = -1;
    @Inject StorageManager _storageMgr;
    @Inject AsyncJobManager _asyncMgr;
    @Inject UserVmManager _vmMgr;
    @Inject UsageEventDao _usageEventDao;
    @Inject HypervisorGuruManager _hvGuruMgr;
    @Inject AccountService _accountService;
    @Inject ResourceLimitService _resourceLimitMgr;
    @Inject SecondaryStorageVmManager _ssvmMgr;
    @Inject LaunchPermissionDao _launchPermissionDao;
    @Inject ProjectManager _projectMgr;
    @Inject
    VolumeDataFactory volFactory;
    @Inject
    ImageDataFactory tmplFactory;
    @Inject
    SnapshotDataFactory snapshotFactory;
    @Inject
    ImageService imageSvr;
    @Inject
    DataStoreManager dataStoreMgr;
    @Inject
    protected ResourceManager _resourceMgr;
    @Inject VolumeManager volumeMgr;
    @Inject VMTemplateHostDao templateHostDao;
    @Inject
    ConfigurationServer _configServer;

    
    int _primaryStorageDownloadWait;
    protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
    
    int _storagePoolMaxWaitSeconds = 3600;
    boolean _disableExtraction = false;
    ExecutorService _preloadExecutor;
    ScheduledExecutorService _swiftTemplateSyncExecutor;
    
    private ScheduledExecutorService _s3TemplateSyncExecutor = null;

    @Inject
    protected List<TemplateAdapter> _adapters;
    
    private TemplateAdapter getAdapter(HypervisorType type) {
    	TemplateAdapter adapter = null;
    	if (type == HypervisorType.BareMetal) {
    		adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName());
    	} else {
    		// see HypervisorTemplateAdapter
    		adapter =  AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName());
    	}
    	
    	if (adapter == null) {
    		throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
    	}
    	
    	return adapter;
    }
    
    @Override
    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
    public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException{
    	TemplateAdapter adapter = getAdapter(HypervisorType.None);
    	TemplateProfile profile = adapter.prepare(cmd);    	
    	VMTemplateVO template = adapter.create(profile);
    	
    	if (template != null){
        	return template;
        }else {
        	throw new CloudRuntimeException("Failed to create ISO");
        }
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template")
    public VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException{
        if(cmd.getTemplateTag() != null){
            Account account = UserContext.current().getCaller();
            if(!_accountService.isRootAdmin(account.getType())){
                throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
            }
        }
        
    	TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
    	TemplateProfile profile = adapter.prepare(cmd);
    	VMTemplateVO template = adapter.create(profile);
    	
    	if (template != null){
        	return template;
        }else {
        	throw new CloudRuntimeException("Failed to create a template");
        }
    }
    
    @Override
    public DataStore getImageStore(String storeUuid, Long zoneId) {
        DataStore imageStore = null;
        if (storeUuid != null) {
            imageStore = this.dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image);
        } else {
            List<DataStore> stores = this.dataStoreMgr.getImageStores(new ZoneScope(zoneId));
            if (stores.size() > 1) {
                throw new CloudRuntimeException("multiple image stores, don't know which one to use");
            }
            imageStore = stores.get(0);
        }
        
        return imageStore;
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true)
    public Long extract(ExtractIsoCmd cmd) {
        Account account = UserContext.current().getCaller();
        Long templateId = cmd.getId();
        Long zoneId = cmd.getZoneId();
        String url = cmd.getUrl();
        String mode = cmd.getMode();
        Long eventId = cmd.getStartEventId();
        
        // FIXME: async job needs fixing
        Long uploadId = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr);
        if (uploadId != null){
        	return uploadId;
        }else {
        	throw new CloudRuntimeException("Failed to extract the iso");
        }
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true)
    public Long extract(ExtractTemplateCmd cmd) {
        Account caller = UserContext.current().getCaller();
        Long templateId = cmd.getId();
        Long zoneId = cmd.getZoneId();
        String url = cmd.getUrl();
        String mode = cmd.getMode();
        Long eventId = cmd.getStartEventId();

        VirtualMachineTemplate template = getTemplate(templateId);
        if (template == null) {
            throw new InvalidParameterValueException("unable to find template with id " + templateId);
        }
        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
        TemplateProfile profile = adapter.prepareExtractTemplate(cmd);

        // FIXME: async job needs fixing
        Long uploadId = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr);
        if (uploadId != null){
        	return uploadId;
        }else {
        	throw new CloudRuntimeException("Failed to extract the teamplate");
        }
    }
    
    @Override
    public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) {
    	
    	VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
    	if(vmTemplate == null)
    		throw new InvalidParameterValueException("Unable to find template id=" + templateId);
    	
    	_accountMgr.checkAccess(UserContext.current().getCaller(), AccessType.ModifyEntry, true, vmTemplate);
    	
    	prepareTemplateInAllStoragePools(vmTemplate, zoneId);
    	return vmTemplate;
    }

    private Long extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) {
        String desc = Upload.Type.TEMPLATE.toString();
        if (isISO) {
            desc = Upload.Type.ISO.toString();
        }
        eventId = eventId == null ? 0:eventId;
        
        if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) {
            throw new PermissionDeniedException("Extraction has been disabled by admin");
        }
        
        VMTemplateVO template = _tmpltDao.findById(templateId);
        if (template == null || template.getRemoved() != null) {
            throw new InvalidParameterValueException("Unable to find " +desc+ " with id " + templateId);
        }
        
        if (template.getTemplateType() ==  Storage.TemplateType.SYSTEM){
            throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template");
        } else if (template.getTemplateType() ==  Storage.TemplateType.PERHOST){
            throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM");
        }
        
        if (isISO) {
            if (template.getFormat() != ImageFormat.ISO ){
                throw new InvalidParameterValueException("Unsupported format, could not extract the ISO");
            }
        } else {
            if (template.getFormat() == ImageFormat.ISO ){
                throw new InvalidParameterValueException("Unsupported format, could not extract the template");
            }
        }
        
		if (zoneId == null && _swiftMgr.isSwiftEnabled()) {
            zoneId = _swiftMgr.chooseZoneForTmpltExtract(templateId);
        }

        if (zoneId == null && _s3Mgr.isS3Enabled()) {
            zoneId = _s3Mgr.chooseZoneForTemplateExtract(template);
        }

        if (_dcDao.findById(zoneId) == null) {
            throw new IllegalArgumentException("Please specify a valid zone.");
        }
        
        if (!_accountMgr.isRootAdmin(caller.getType()) && !template.isExtractable()) {
            throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable");
        }
        
        _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
        
        List<HostVO> sservers = getSecondaryStorageHosts(zoneId);

        VMTemplateHostVO tmpltHostRef = null;
        if (sservers != null) {
            for(HostVO secondaryStorageHost: sservers){
                tmpltHostRef = _tmpltHostDao.findByHostTemplate(secondaryStorageHost.getId(), templateId);
                if (tmpltHostRef != null){
                    if (tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
                        tmpltHostRef = null;
                    }
                    else {
                        break;
                    }
                }
            }
        }
        
        if (tmpltHostRef == null && _swiftMgr.isSwiftEnabled()) {
            SwiftTO swift = _swiftMgr.getSwiftTO(templateId);
            if (swift != null && sservers != null) {
                downloadTemplateFromSwiftToSecondaryStorage(zoneId, templateId);
            }
        } else if (tmpltHostRef == null && _s3Mgr.isS3Enabled()) {
            if (sservers != null) {
                _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(zoneId,
                        templateId, _primaryStorageDownloadWait);
            }
        }

        if (tmpltHostRef == null) {
            throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
        }
        
        Upload.Mode extractMode;
        if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){
            throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD);
        } else {
            extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD;
        }
        
        if (extractMode == Upload.Mode.FTP_UPLOAD){
            URI uri = null;
            try {
                uri = new URI(url);
                if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp") )) {
                   throw new InvalidParameterValueException("Unsupported scheme for url: " + url);
                }
            } catch (Exception ex) {
                throw new InvalidParameterValueException("Invalid url given: " + url);
            }
    
            String host = uri.getHost();
            try {
                InetAddress hostAddr = InetAddress.getByName(host);
                if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress() ) {
                    throw new InvalidParameterValueException("Illegal host specified in url");
                }
                if (hostAddr instanceof Inet6Address) {
                    throw new InvalidParameterValueException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")");
                }
            } catch (UnknownHostException uhe) {
                throw new InvalidParameterValueException("Unable to resolve " + host);
            }
                    
            if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE) ){
                throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same"); 
            }
        
            return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr);            
        }
        
        UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltHostRef, zoneId, eventId);
        if (vo != null){                                  
            return vo.getId();
        }else{
            return null;
        }
    }
    
    public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
    	List<StoragePoolVO> pools = _poolDao.listByStatus(StoragePoolStatus.Up);
    	for(final StoragePoolVO pool : pools) {
    		if(pool.getDataCenterId() == zoneId) {
    			s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
	    		this._preloadExecutor.execute(new Runnable() {
	    			public void run() {
	    				try {
	    					reallyRun();
	    				} catch(Throwable e) {
	    					s_logger.warn("Unexpected exception ", e);
	    				}
	    			}
	    			
	    			private void reallyRun() {
	        			s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
	        			StoragePool pol = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId());
	        			prepareTemplateForCreate(template, pol);
	        			s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId());
	    			}
	    		});
    		} else {
    			s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + pool.getDataCenterId() + " is ");
    		}
    	}
    }
    
    String downloadTemplateFromSwiftToSecondaryStorage(long dcId, long templateId){
        VMTemplateVO template = _tmpltDao.findById(templateId);
        if ( template == null ) {
            String errMsg = " Can not find template " + templateId;
            s_logger.warn(errMsg);
            return errMsg;
        }
        VMTemplateSwiftVO tmpltSwift = _swiftMgr.findByTmpltId(templateId);
        if ( tmpltSwift == null ) {
            String errMsg = " Template " + templateId + " doesn't exist in swift";
            s_logger.warn(errMsg);
            return errMsg;
        }
        SwiftTO swift = _swiftMgr.getSwiftTO(tmpltSwift.getSwiftId());
        if ( swift == null ) {
            String errMsg = " Swift " + tmpltSwift.getSwiftId() + " doesn't exit ?";
            s_logger.warn(errMsg);
            return errMsg;
        }

        HostVO secHost = _ssvmMgr.findSecondaryStorageHost(dcId);
        if ( secHost == null ) {
            String errMsg = "Can not find secondary storage in data center " + dcId;
            s_logger.warn(errMsg);
            return errMsg;
        }

        DownloadTemplateFromSwiftToSecondaryStorageCommand cmd = new DownloadTemplateFromSwiftToSecondaryStorageCommand(swift, secHost.getName(), dcId, template.getAccountId(), templateId,
                tmpltSwift.getPath(), _primaryStorageDownloadWait);
        try {
            Answer answer = _agentMgr.sendToSSVM(dcId, cmd);
            if (answer == null || !answer.getResult()) {
                String errMsg = "Failed to download template from Swift to secondary storage due to " + (answer == null ? "answer is null" : answer.getDetails());
                s_logger.warn(errMsg);
                throw new CloudRuntimeException(errMsg);
            }
            String installPath = "template/tmpl/" + template.getAccountId() + "/" + template.getId() + "/" + tmpltSwift.getPath();
            VMTemplateHostVO tmpltHost = new VMTemplateHostVO(secHost.getId(), templateId, new Date(), 100, Status.DOWNLOADED, null, null, null, installPath, template.getUrl());
            tmpltHost.setSize(tmpltSwift.getSize());
            tmpltHost.setPhysicalSize(tmpltSwift.getPhysicalSize());
            _tmpltHostDao.persist(tmpltHost);
        } catch (Exception e) {
            String errMsg = "Failed to download template from Swift to secondary storage due to " + e.toString();
            s_logger.warn(errMsg);
            throw new CloudRuntimeException(errMsg);
        }
        return null;
    }

    String uploadTemplateToSwiftFromSecondaryStorage(VMTemplateHostVO templateHostRef) {
        Long templateId = templateHostRef.getTemplateId();
        VMTemplateVO template = _tmpltDao.findById(templateId);
        if (template == null) {
            String errMsg = " Can not find template " + templateId;
            s_logger.warn(errMsg);
            return errMsg;
        }

        if (template.getTemplateType() == TemplateType.PERHOST) {
            return null;
        }

        SwiftTO swift = _swiftMgr.getSwiftTO();
        if (swift == null) {
            String errMsg = " There is no Swift in this setup ";
            s_logger.warn(errMsg);
            return errMsg;
        }

        HostVO secHost = _hostDao.findById(templateHostRef.getHostId());
        if (secHost == null) {
            String errMsg = "Can not find secondary storage " + templateHostRef.getHostId();
            s_logger.warn(errMsg);
            return errMsg;
        }

        UploadTemplateToSwiftFromSecondaryStorageCommand cmd = new UploadTemplateToSwiftFromSecondaryStorageCommand(swift, secHost.getName(), secHost.getDataCenterId(), template.getAccountId(),
                templateId, _primaryStorageDownloadWait);
        Answer answer = null;
        try {
            answer = _agentMgr.sendToSSVM(secHost.getDataCenterId(), cmd);
            if (answer == null || !answer.getResult()) {
                if (template.getTemplateType() != TemplateType.SYSTEM) {
                    String errMsg = "Failed to upload template " + templateId + " to Swift from secondary storage due to " + ((answer == null) ? "null" : answer.getDetails());
                    s_logger.warn(errMsg);
                    throw new CloudRuntimeException(errMsg);
                }
                return null;
            }
            String path = templateHostRef.getInstallPath();
            int index = path.lastIndexOf('/');
            path = path.substring(index + 1);
            VMTemplateSwiftVO tmpltSwift = new VMTemplateSwiftVO(swift.getId(), templateHostRef.getTemplateId(), new Date(), path, templateHostRef.getSize(), templateHostRef.getPhysicalSize());
            _tmpltSwiftDao.persist(tmpltSwift);
            _swiftMgr.propagateTemplateOnAllZones(templateHostRef.getTemplateId());
        } catch (Exception e) {
            String errMsg = "Failed to upload template " + templateId + " to Swift from secondary storage due to " + e.toString();
            s_logger.warn(errMsg);
            throw new CloudRuntimeException(errMsg);
        }
        return null;
    }

    @Override @DB
    public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
    	VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
    	
        long poolId = pool.getId();
        long templateId = template.getId();
        long dcId = pool.getDataCenterId();
        VMTemplateStoragePoolVO templateStoragePoolRef = null;
        VMTemplateHostVO templateHostRef = null;
        long templateStoragePoolRefId;
        String origUrl = null;
        
        templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
        if (templateStoragePoolRef != null) {
        	templateStoragePoolRef.setMarkedForGC(false);
            _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
            
            if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
	            if (s_logger.isDebugEnabled()) {
	                s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId);
	            }
	            
	            return templateStoragePoolRef;
	        }
        }
        
        templateHostRef = findVmTemplateHost(templateId, pool);
        
        if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
            String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
            if (result != null) {
                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
                return null;
            }
            result = _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(dcId,
                    templateId, _primaryStorageDownloadWait);
            if (result != null) {
                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
                return null;
            }
            templateHostRef = findVmTemplateHost(templateId, pool);
            if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
                return null;
            }
        }
        
        HostVO sh = _hostDao.findById(templateHostRef.getHostId());
        origUrl = sh.getStorageUrl();
        if (origUrl == null) {
            throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString());
        }
        
        if (templateStoragePoolRef == null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
            }
            templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId);
            try {
                templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef);
                templateStoragePoolRefId =  templateStoragePoolRef.getId();
                
            } catch (Exception e) {
                s_logger.debug("Assuming we're in a race condition: " + e.getMessage());
                templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
                if (templateStoragePoolRef == null) {
                    throw new CloudRuntimeException("Unable to persist a reference for pool " + poolId + " and template " + templateId);
                }
                templateStoragePoolRefId = templateStoragePoolRef.getId();
            }
        } else {
            templateStoragePoolRefId = templateStoragePoolRef.getId();
        }
        
        List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
        if (vos == null || vos.isEmpty()){
        	 throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");            
        }                
        
        templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds);
        if (templateStoragePoolRef == null) {
            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId);
        }

        try {
            if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
                return templateStoragePoolRef;
            }
            String url = origUrl + "/" + templateHostRef.getInstallPath();
            PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(), 
                   template.getAccountId(), pool, _primaryStorageDownloadWait);
            HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
            assert(secondaryStorageHost != null);
            dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl());
            // TODO temporary hacking, hard-coded to NFS primary data store
            dcmd.setPrimaryStorageUrl("nfs://" + pool.getHostAddress() + pool.getPath());
            
            for (int retry = 0; retry < 2; retry ++){
            	Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries
            	StoragePoolHostVO vo = vos.get(0);
	            if (s_logger.isDebugEnabled()) {
	                s_logger.debug("Downloading " + templateId + " via " + vo.getHostId());
	            }
	        	dcmd.setLocalPath(vo.getLocalPath());
	        	// set 120 min timeout for this command
	        	
	        	PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend(
	                   _hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd);
	            if (answer != null && answer.getResult() ) {
	        		templateStoragePoolRef.setDownloadPercent(100);
	        		templateStoragePoolRef.setDownloadState(Status.DOWNLOADED);
	        		templateStoragePoolRef.setLocalDownloadPath(answer.getInstallPath());
	        		templateStoragePoolRef.setInstallPath(answer.getInstallPath());
	        		templateStoragePoolRef.setTemplateSize(answer.getTemplateSize());
	        		_tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
	        		if (s_logger.isDebugEnabled()) {
	        			s_logger.debug("Template " + templateId + " is downloaded via " + vo.getHostId());
	        		}
	        		return templateStoragePoolRef;
	            } else {
	                if (s_logger.isDebugEnabled()) {
	                    s_logger.debug("Template " + templateId + " download to pool " + vo.getPoolId() + " failed due to " + (answer!=null?answer.getDetails():"return null"));                }
	            }
            }
        } finally {
            _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
        }
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Template " + templateId + " is not found on and can not be downloaded to pool " + poolId);
        }
        return null;
    }
    
    
    
    
    @Override
    public VMTemplateHostVO findVmTemplateHost(long templateId,
            StoragePool pool) {
        long dcId = pool.getDataCenterId();
        Long podId = pool.getPodId();

        List<HostVO> secHosts = _ssvmMgr
                .listSecondaryStorageHostsInOneZone(dcId);


        if (secHosts.size() == 1) {
            VMTemplateHostVO templateHostVO = this._tmpltHostDao
                    .findByHostTemplate(secHosts.get(0).getId(), templateId);
            return templateHostVO;
        }
        if (podId != null) {
            List<VMTemplateHostVO> templHosts = this._tmpltHostDao
                    .listByTemplateStatus(templateId, dcId, podId,
                            VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
            if (templHosts != null && !templHosts.isEmpty()) {
                Collections.shuffle(templHosts);
                return templHosts.get(0);
            }
        }
        List<VMTemplateHostVO> templHosts = this._tmpltHostDao
                .listByTemplateStatus(templateId, dcId,
                        VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
        if (templHosts != null && !templHosts.isEmpty()) {
            Collections.shuffle(templHosts);
            return templHosts.get(0);
        }
        return null;
    }
    
    @Override
    public String getChecksum(Long hostId, String templatePath) {
        HostVO ssHost = _hostDao.findById(hostId);
        Host.Type type = ssHost.getType();
        if (type != Host.Type.SecondaryStorage
                && type != Host.Type.LocalSecondaryStorage) {
            return null;
        }
        String secUrl = ssHost.getStorageUrl();
        Answer answer;
        answer = _agentMgr.sendToSecStorage(ssHost, new ComputeChecksumCommand(
                secUrl, templatePath));
        if (answer != null && answer.getResult()) {
            return answer.getDetails();
        }
        return null;
    }
    
    @Override
    @DB
    public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) {
        template = _tmpltDao.findById(template.getId(), true);

        long poolId = pool.getId();
        long templateId = template.getId();
        long dcId = pool.getDataCenterId();
        VMTemplateStoragePoolVO templateStoragePoolRef = null;
        VMTemplateHostVO templateHostRef = null;
        long templateStoragePoolRefId;
        String origUrl = null;

        templateHostRef = findVmTemplateHost(templateId, pool);

        if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
            String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
            if (result != null) {
                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
                return null;
            }
            result = _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(dcId,
                    templateId, _primaryStorageDownloadWait);
            if (result != null) {
                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
                return null;
            }
            templateHostRef = findVmTemplateHost(templateId, pool);
            if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
                s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
                return null;
            }
        }
        return templateHostRef;
    }

    @Override
    @DB
    public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) {
    	// have to use the same lock that prepareTemplateForCreate use to maintain state consistency
    	VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200);
    	
        if (templateStoragePoolRef == null) {
        	s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId);
            return false;
        }
        
        try {
        	templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
        	_tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef);
        } finally {
            _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
        }
        
        return true;
    }
    
    @Override
    @DB
    public boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
        List<HostVO> dstSecHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dstZone.getId());
        long tmpltId = template.getId();
        long dstZoneId = dstZone.getId();
        if (dstSecHosts == null || dstSecHosts.isEmpty() ) {
            throw new StorageUnavailableException("Destination zone is not ready", DataCenter.class, dstZone.getId());
        }
        AccountVO account = _accountDao.findById(template.getAccountId());
        VMTemplateHostVO srcTmpltHost = _tmpltHostDao.findByHostTemplate(srcSecHost.getId(), tmpltId);

        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
        _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltHost.getSize()));

        // Event details
        String copyEventType;
        String createEventType;
        if (template.getFormat().equals(ImageFormat.ISO)){
            copyEventType = EventTypes.EVENT_ISO_COPY;
            createEventType = EventTypes.EVENT_ISO_CREATE;
        } else {
            copyEventType = EventTypes.EVENT_TEMPLATE_COPY;
            createEventType = EventTypes.EVENT_TEMPLATE_CREATE;
        }

        Transaction txn = Transaction.currentTxn();
        txn.start();

        for ( HostVO dstSecHost : dstSecHosts ) {
            VMTemplateHostVO dstTmpltHost = null;
            try {
            	dstTmpltHost = _tmpltHostDao.findByHostTemplate(dstSecHost.getId(), tmpltId, true);
            	if (dstTmpltHost != null) {
            		dstTmpltHost = _tmpltHostDao.lockRow(dstTmpltHost.getId(), true);
            		if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOADED) {
            			if (dstTmpltHost.getDestroyed() == false)  {
            				return true;
            			} else {
            				dstTmpltHost.setDestroyed(false);
            				_tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost);
            				
            				return true;
            			}
            		} else if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOAD_ERROR){
            			if (dstTmpltHost.getDestroyed() == true)  {
            				dstTmpltHost.setDestroyed(false);
            				dstTmpltHost.setDownloadState(Status.NOT_DOWNLOADED);
            				dstTmpltHost.setDownloadPercent(0);
            				dstTmpltHost.setCopy(true);
            				dstTmpltHost.setErrorString("");
            				dstTmpltHost.setJobId(null);
            				_tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost);
            			}
            		}
            	}
            } finally {
            	txn.commit();
            }

            if(_downloadMonitor.copyTemplate(template, srcSecHost, dstSecHost) ) {
                _tmpltDao.addTemplateToZone(template, dstZoneId);
            	
            	if(account.getId() != Account.ACCOUNT_ID_SYSTEM){
                    UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(),
                            template.getClass().getName(), template.getUuid());
            	}
            	return true;
            }
        }
        return false;
    }
  
    
    @Override
    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
    public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
    	Long templateId = cmd.getId();
    	Long userId = UserContext.current().getCallerUserId();
    	Long sourceZoneId = cmd.getSourceZoneId();
    	Long destZoneId = cmd.getDestinationZoneId();
    	Account caller = UserContext.current().getCaller();
        
        if (_swiftMgr.isSwiftEnabled()) {
            throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones");
        }

        if (_s3Mgr.isS3Enabled()) {
            throw new CloudRuntimeException(
                    "copytemplate API is disabled in S3 setup -- S3 templates are accessible in all zones.");
        }

        //Verify parameters
        if (sourceZoneId.equals(destZoneId)) {
            throw new InvalidParameterValueException("Please specify different source and destination zones.");
        }
        
        DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
        if (sourceZone == null) {
            throw new InvalidParameterValueException("Please specify a valid source zone.");
        }
        
        DataCenterVO dstZone = _dcDao.findById(destZoneId);
        if (dstZone == null) {
            throw new InvalidParameterValueException("Please specify a valid destination zone.");
        }
    	
        VMTemplateVO template = _tmpltDao.findById(templateId);
        if (template == null || template.getRemoved() != null) {
            throw new InvalidParameterValueException("Unable to find template with id");
        }
      
        HostVO dstSecHost = getSecondaryStorageHost(destZoneId, templateId);
        if ( dstSecHost != null ) {
            s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecHost.getId() + " in zone " + destZoneId + " , don't need to copy");
            return template;
        }
        
        HostVO srcSecHost = getSecondaryStorageHost(sourceZoneId, templateId);
        if ( srcSecHost == null ) {
            throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId );
        }
       
        _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
        
        boolean success = copy(userId, template, srcSecHost, sourceZone, dstZone);
        
    	if (success){
        	return template;
        }else {
        	throw new CloudRuntimeException("Failed to copy template");
        }
    }

    @Override
    public boolean delete(long userId, long templateId, Long zoneId) {
    	VMTemplateVO template = _tmpltDao.findById(templateId);
    	if (template == null || template.getRemoved() != null) {
    		throw new InvalidParameterValueException("Please specify a valid template.");
    	}
    	
    	TemplateAdapter adapter = getAdapter(template.getHypervisorType());
    	return adapter.delete(new TemplateProfile(userId, template, zoneId));
    }
    
    @Override
    public List<VMTemplateStoragePoolVO> getUnusedTemplatesInPool(StoragePoolVO pool) {
		List<VMTemplateStoragePoolVO> unusedTemplatesInPool = new ArrayList<VMTemplateStoragePoolVO>();
		List<VMTemplateStoragePoolVO> allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId());
		
		for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) {
			VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());			
		
			// If this is a routing template, consider it in use
			if (template.getTemplateType() == TemplateType.SYSTEM) {
				continue;
			}
			
			// If the template is not yet downloaded to the pool, consider it in use
			if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) {
				continue;
			}

			if (template.getFormat() != ImageFormat.ISO && !_volumeDao.isAnyVolumeActivelyUsingTemplateOnPool(template.getId(), pool.getId())) {
                unusedTemplatesInPool.add(templatePoolVO);
			}
		}
		
		return unusedTemplatesInPool;
	}
    
    @Override
    public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
        StoragePool pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
		VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
		
		
		if (s_logger.isDebugEnabled()) {
		    s_logger.debug("Evicting " + templatePoolVO);
		}
		DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
		
        try {
            Answer answer = _storageMgr.sendToPool(pool, cmd);
		
            if (answer != null && answer.getResult()) {
                // Remove the templatePoolVO
                if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
                    s_logger.debug("Successfully evicted template: " + template.getName() + " from storage pool: " + pool.getName());
                }
            } else {
                s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
            }
        } catch (StorageUnavailableException e) {
            s_logger.info("Storage is unavailable currently.  Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName());
        }

	}
    
    void swiftTemplateSync() {
        GlobalLock swiftTemplateSyncLock = GlobalLock.getInternLock("templatemgr.swiftTemplateSync");
        try {
            if (!_swiftMgr.isSwiftEnabled()) {
                return;
            }
            List<HypervisorType> hypers = _clusterDao.getAvailableHypervisorInZone(null);
            List<VMTemplateVO> templates = _tmpltDao.listByHypervisorType(hypers);
            List<Long> templateIds = new ArrayList<Long>();
            for (VMTemplateVO template : templates) {
                if (template.getTemplateType() != TemplateType.PERHOST) {
                    templateIds.add(template.getId());
                }
            }
            List<VMTemplateSwiftVO> templtSwiftRefs = _tmpltSwiftDao.listAll();
            for (VMTemplateSwiftVO templtSwiftRef : templtSwiftRefs) {
                templateIds.remove((Long) templtSwiftRef.getTemplateId());
            }
            if (templateIds.size() < 1) {
                return;
            }
            if (swiftTemplateSyncLock.lock(3)) {
                try {
                    List<VMTemplateHostVO> templtHostRefs = _tmpltHostDao.listByState(VMTemplateHostVO.Status.DOWNLOADED);
                    for (VMTemplateHostVO templtHostRef : templtHostRefs) {
                        if (templtHostRef.getDestroyed()) {
                            continue;
                        }
                        if (!templateIds.contains(templtHostRef.getTemplateId())) {
                            continue;
                        }
                        try {
                            uploadTemplateToSwiftFromSecondaryStorage(templtHostRef);
                        } catch (Exception e) {
                            s_logger.debug("failed to upload template " + templtHostRef.getTemplateId() + " to Swift due to " + e.toString());
                        }
                    }
                } catch (Throwable e) {
                    s_logger.error("Problem with sync swift template due to " + e.toString(), e);
                } finally {
                    swiftTemplateSyncLock.unlock();
                }
            }
        } catch (Throwable e) {
            s_logger.error("Problem with sync swift template due to " + e.toString(), e);
        } finally {
            swiftTemplateSyncLock.releaseRef();
        }
    }

    private Runnable getSwiftTemplateSyncTask() {
        return new Runnable() {
            @Override
            public void run() {
                if (s_logger.isDebugEnabled()) {
                    s_logger.trace("Start Swift Template sync at" + (new Date()));
                }
                swiftTemplateSync();
                if (s_logger.isTraceEnabled()) {
                    s_logger.trace("Finish Swift Template sync at" + (new Date()));
                }
            }
        };
    }

    @Override
    public boolean start() {
        _swiftTemplateSyncExecutor.scheduleAtFixedRate(getSwiftTemplateSyncTask(), 60, 60, TimeUnit.SECONDS);

        if (_s3TemplateSyncExecutor != null) {

            final int initialDelay = 60;
            final int period = 60;

            _s3TemplateSyncExecutor.scheduleAtFixedRate(new S3SyncTask(
                    this._tmpltDao, this._s3Mgr), initialDelay, period,
                    TimeUnit.SECONDS);
            s_logger.info(String.format("Started S3 sync task to execute "
                    + "execute every %1$s after an initial delay of %2$s.",
                    period, initialDelay));

        }

        return true;
    }

    @Override
    public boolean stop() {
        _swiftTemplateSyncExecutor.shutdownNow();

        if (_s3TemplateSyncExecutor != null) {
            _s3TemplateSyncExecutor.shutdownNow();
        }

        return true;
    }

    @Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
        
        final Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
        _routerTemplateId = NumbersUtil.parseInt(configs.get("router.template.id"), 1);

        String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
        _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));

        String disableExtraction =  _configDao.getValue(Config.DisableExtraction.toString());
        _disableExtraction  = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction);

        HostTemplateStatesSearch = _tmpltHostDao.createSearchBuilder();
        HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
        HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
        
        SearchBuilder<HostVO> HostSearch = _hostDao.createSearchBuilder();
        HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
        
        HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER);
        HostSearch.done();
        HostTemplateStatesSearch.done();
        
        _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
        _preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader"));
        _swiftTemplateSyncExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("swift-template-sync-Executor"));

        if (_s3Mgr.isS3Enabled()) {
            _s3TemplateSyncExecutor = Executors
                    .newSingleThreadScheduledExecutor(new NamedThreadFactory(
                            "s3-template-sync"));
        } else {
            s_logger.info("S3 secondary storage synchronization is disabled.");
        }

        return true;
    }
    
    protected TemplateManagerImpl() {
    }

	@Override
	public boolean templateIsDeleteable(VMTemplateHostVO templateHostRef) {
	    VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateHostRef.getTemplateId());
	    long templateId = template.getId();
	    HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
	    long zoneId = secondaryStorageHost.getDataCenterId();
	    DataCenterVO zone = _dcDao.findById(zoneId);

	    // Check if there are VMs running in the template host ref's zone that use the template
	    List<VMInstanceVO> nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId);

	    if (!nonExpungedVms.isEmpty()) {
	        s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are non-expunged VMs deployed from this template.");
	        return false;
	    }
	    List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
	    //check if there is any VM using this ISO.
	    if (!userVmUsingIso.isEmpty()) {
	        s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
	        return false;
	    }
	    // Check if there are any snapshots for the template in the template host ref's zone
	    List<VolumeVO> volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId);
	    for (VolumeVO volume : volumes) {
	        List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1");
	        if (!snapshots.isEmpty()) {
	            s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are 2.1 snapshots using this template.");
	            return false;
	        }
	    }

	    return true;
	}

	@Override
    @ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true)
	public boolean detachIso(long vmId)  {
        Account caller = UserContext.current().getCaller();
        Long userId = UserContext.current().getCallerUserId();
        
        // Verify input parameters
        UserVmVO vmInstanceCheck = _userVmDao.findById(vmId);
        if (vmInstanceCheck == null) {
            throw new InvalidParameterValueException ("Unable to find a virtual machine with id " + vmId);
        }
        
        UserVm userVM = _userVmDao.findById(vmId);
        if (userVM == null) {
            throw new InvalidParameterValueException("Please specify a valid VM.");
        }
        
        _accountMgr.checkAccess(caller, null, true, userVM);

        Long isoId = userVM.getIsoId();
        if (isoId == null) {
            throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
        }
    	UserContext.current().setEventDetails("Vm Id: " +vmId+ " ISO Id: "+isoId);
        
        State vmState = userVM.getState();
        if (vmState != State.Running && vmState != State.Stopped) {
        	throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
        }

        boolean result = attachISOToVM(vmId, userId, isoId, false); //attach=false => detach
        if (result){
        	return result;
        }else {
        	throw new CloudRuntimeException("Failed to detach iso");
        }        
	}
	
	@Override
    @ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true)
	public boolean attachIso(long isoId, long vmId) {
        Account caller = UserContext.current().getCaller();
        Long userId = UserContext.current().getCallerUserId();
        
    	// Verify input parameters
    	UserVmVO vm = _userVmDao.findById(vmId);
    	if (vm == null) {
            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
        }
    	
    	VMTemplateVO iso = _tmpltDao.findById(isoId);
    	if (iso == null || iso.getRemoved() != null) {
            throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId);
    	}
    	
    	//check permissions
    	//check if caller has access to VM and ISO 
    	//and also check if the VM's owner has access to the ISO.
    	
    	_accountMgr.checkAccess(caller, null, false, iso, vm);
    	
    	Account vmOwner = _accountDao.findById(vm.getAccountId());
    	_accountMgr.checkAccess(vmOwner, null, false, iso, vm);
    	
        State vmState = vm.getState();
        if (vmState != State.Running && vmState != State.Stopped) {
        	throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
        }
        
        if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer){
        	throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType());
        }
        
        if("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
        	throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType());
        }
        boolean result = attachISOToVM(vmId, userId, isoId, true);
        if (result){
        	return result;
        }else {
        	throw new CloudRuntimeException("Failed to attach iso");
        }
	}
	
    private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
        UserVmVO vm = this._userVmDao.findById(vmId);

        if (vm == null) {
            return false;
        } else if (vm.getState() != State.Running) {
            return true;
        }
        String isoPath;
        VMTemplateVO tmplt = this._tmpltDao.findById(isoId);
        if (tmplt == null) {
            s_logger.warn("ISO: " + isoId + " does not exist");
            return false;
        }
        // Get the path of the ISO
        Pair<String, String> isoPathPair = null;
        if (tmplt.getTemplateType() == TemplateType.PERHOST) {
            isoPath = tmplt.getName();
        } else {
            isoPathPair = getAbsoluteIsoPath(isoId,
                    vm.getDataCenterId());
            if (isoPathPair == null) {
                s_logger.warn("Couldn't get absolute iso path");
                return false;
            } else {
                isoPath = isoPathPair.first();
            }
        }

        String vmName = vm.getInstanceName();

        HostVO host = _hostDao.findById(vm.getHostId());
        if (host == null) {
            s_logger.warn("Host: " + vm.getHostId() + " does not exist");
            return false;
        }
        AttachIsoCommand cmd = new AttachIsoCommand(vmName, isoPath, attach);
        if (isoPathPair != null) {
            cmd.setStoreUrl(isoPathPair.second());
        }
        Answer a = _agentMgr.easySend(vm.getHostId(), cmd);

        return (a != null && a.getResult());
    }

    private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) {
    	UserVmVO vm = _userVmDao.findById(vmId);
    	VMTemplateVO iso = _tmpltDao.findById(isoId);

        boolean success = attachISOToVM(vmId, isoId, attach);
        if ( success && attach) {
             vm.setIsoId(iso.getId());
            _userVmDao.update(vmId, vm);
        } 
        if ( success && !attach ) {
            vm.setIsoId(null);
            _userVmDao.update(vmId, vm);
        }    
        return success;
    }
	
	@Override
    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true)
    public boolean deleteTemplate(DeleteTemplateCmd cmd) {
        Long templateId = cmd.getId();
        Account caller = UserContext.current().getCaller();
        
        VirtualMachineTemplate template = getTemplate(templateId);
        if (template == null) {
            throw new InvalidParameterValueException("unable to find template with id " + templateId);
        }
        
        _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
    	
    	if (template.getFormat() == ImageFormat.ISO) {
    		throw new InvalidParameterValueException("Please specify a valid template.");
    	}
        if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) {
            _swiftMgr.deleteTemplate(cmd);
        }
        if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) {
            _s3Mgr.deleteTemplate(cmd.getId(), caller.getAccountId());
        }

    	TemplateAdapter adapter = getAdapter(template.getHypervisorType());
    	TemplateProfile profile = adapter.prepareDelete(cmd);
    	boolean result = adapter.delete(profile);
    	
    	if (result){
            if (cmd.getZoneId() == null
                    && (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) {
                List<VMTemplateZoneVO> templateZones = _tmpltZoneDao
                        .listByZoneTemplate(null, templateId);
                if (templateZones != null) {
                    for (VMTemplateZoneVO templateZone : templateZones) {
                        _tmpltZoneDao.remove(templateZone.getId());
                    }
                }
            }
    		return true;
    	}else{
    		throw new CloudRuntimeException("Failed to delete template");
    	}
	}
	
	@Override
    @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true)
    public boolean deleteIso(DeleteIsoCmd cmd) {
        Long templateId = cmd.getId();
        Account caller = UserContext.current().getCaller();
        Long zoneId = cmd.getZoneId();
        
        VirtualMachineTemplate template = getTemplate(templateId);;
        if (template == null) {
            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
        }
        
        _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
         	
    	if (template.getFormat() != ImageFormat.ISO) {
    		throw new InvalidParameterValueException("Please specify a valid iso.");
    	}
        if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) {
            _swiftMgr.deleteIso(cmd);
    	}
        if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) {
            _s3Mgr.deleteTemplate(caller.getAccountId(), templateId);
        }

    	if (zoneId != null && (_ssvmMgr.findSecondaryStorageHost(zoneId) == null)) {
    		throw new InvalidParameterValueException("Failed to find a secondary storage host in the specified zone.");
    	}
    	TemplateAdapter adapter = getAdapter(template.getHypervisorType());
    	TemplateProfile profile = adapter.prepareDelete(cmd);
        boolean result = adapter.delete(profile);
        if (result) {
            if (cmd.getZoneId() == null
                    && (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) {
                List<VMTemplateZoneVO> templateZones = _tmpltZoneDao
                        .listByZoneTemplate(null, templateId);
                if (templateZones != null) {
                    for (VMTemplateZoneVO templateZone : templateZones) {
                        _tmpltZoneDao.remove(templateZone.getId());
                    }
                }
            }
            return true;
        } else {
    		throw new CloudRuntimeException("Failed to delete ISO");
    	}
	}
	
	@Override
	public VirtualMachineTemplate getTemplate(long templateId) {
	    VMTemplateVO template = _tmpltDao.findById(templateId);
	    if (template != null && template.getRemoved() == null) {
	        return template;
	    }
	    
	    return null;
	}
	
    @Override
    public List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) {
        Account caller = UserContext.current().getCaller();
        Long id = cmd.getId();

        if (id.equals(Long.valueOf(1))) {
            throw new PermissionDeniedException("unable to list permissions for " + cmd.getMediaType() + " with id " + id);
        }

        VirtualMachineTemplate template = getTemplate(id);
        if (template == null) {
            throw new InvalidParameterValueException("unable to find " + cmd.getMediaType() + " with id " + id);
        }
        
        if (cmd instanceof ListTemplatePermissionsCmd) {
            if (template.getFormat().equals(ImageFormat.ISO)) {
                throw new InvalidParameterValueException("Please provide a valid template");
            }
        } else if (cmd instanceof ListIsoPermissionsCmd) {
            if (!template.getFormat().equals(ImageFormat.ISO)) {
                throw new InvalidParameterValueException("Please provide a valid iso");
            }
        }

        if (!template.isPublicTemplate()) {
            _accountMgr.checkAccess(caller, null, true, template);
        }

        List<String> accountNames = new ArrayList<String>();
        List<LaunchPermissionVO> permissions = _launchPermissionDao.findByTemplate(id);
        if ((permissions != null) && !permissions.isEmpty()) {
            for (LaunchPermissionVO permission : permissions) {
                Account acct = _accountDao.findById(permission.getAccountId());
                accountNames.add(acct.getAccountName());
            }
        }

        // also add the owner if not public
        if (!template.isPublicTemplate()) {
            Account templateOwner = _accountDao.findById(template.getAccountId());
            accountNames.add(templateOwner.getAccountName());
        }

        return accountNames;
    }
    
    @DB
    @Override
    public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) {
        Transaction txn = Transaction.currentTxn();

        // Input validation
        Long id = cmd.getId();
        Account caller = UserContext.current().getCaller();
        List<String> accountNames = cmd.getAccountNames();
        List<Long> projectIds = cmd.getProjectIds();
        Boolean isFeatured = cmd.isFeatured();
        Boolean isPublic = cmd.isPublic();
        Boolean isExtractable = cmd.isExtractable();
        String operation = cmd.getOperation();
        String mediaType = "";

        VMTemplateVO template = _tmpltDao.findById(id);

        if (template == null) {
            throw new InvalidParameterValueException("unable to find " + mediaType + " with id " + id);
        }

        if (cmd instanceof UpdateTemplatePermissionsCmd) {
            mediaType = "template";
            if (template.getFormat().equals(ImageFormat.ISO)) {
                throw new InvalidParameterValueException("Please provide a valid template");
            }
        }
        if (cmd instanceof UpdateIsoPermissionsCmd) {
            mediaType = "iso";
            if (!template.getFormat().equals(ImageFormat.ISO)) {
                throw new InvalidParameterValueException("Please provide a valid iso");
            }
        }
        
        //convert projectIds to accountNames
        if (projectIds != null) {
            for (Long projectId : projectIds) {
                Project project = _projectMgr.getProject(projectId);
                if (project == null) {
                    throw new InvalidParameterValueException("Unable to find project by id " + projectId);
                }
                
                if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
                    throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId);
                }
                accountNames.add(_accountMgr.getAccount(project.getProjectAccountId()).getAccountName());
            }
        }

        _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);

        // If the template is removed throw an error.
        if (template.getRemoved() != null) {
            s_logger.error("unable to update permissions for " + mediaType + " with id " + id + " as it is removed  ");
            throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id + " as it is removed ");
        }

        if (id.equals(Long.valueOf(1))) {
            throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id);
        }

        boolean isAdmin = _accountMgr.isAdmin(caller.getType());
        // check configuration parameter(allow.public.user.templates) value for the template owner
        boolean allowPublicUserTemplates = Boolean.valueOf(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), template.getAccountId()));
        if (!isAdmin && !allowPublicUserTemplates && isPublic != null && isPublic) {
            throw new InvalidParameterValueException("Only private " + mediaType + "s can be created.");
        }

        if (accountNames != null) {
            if ((operation == null) || (!operation.equalsIgnoreCase("add") && !operation.equalsIgnoreCase("remove") && !operation.equalsIgnoreCase("reset"))) {
                throw new InvalidParameterValueException("Invalid operation on accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions."
                        + "  Given operation is: '" + operation + "'");
            }
        }

        Long accountId = template.getAccountId();
        if (accountId == null) {
            // if there is no owner of the template then it's probably already a public template (or domain private template) so
            // publishing to individual users is irrelevant
            throw new InvalidParameterValueException("Update template permissions is an invalid operation on template " + template.getName());
        }

        VMTemplateVO updatedTemplate = _tmpltDao.createForUpdate();

        if (isPublic != null) {
            updatedTemplate.setPublicTemplate(isPublic.booleanValue());
        }

        if (isFeatured != null) {
            updatedTemplate.setFeatured(isFeatured.booleanValue());
        }
        
       if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {//Only ROOT admins allowed to change this powerful attribute
           updatedTemplate.setExtractable(isExtractable.booleanValue());
       }else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
           throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute.");
       }

       _tmpltDao.update(template.getId(), updatedTemplate);

        Long domainId = caller.getDomainId();
        if ("add".equalsIgnoreCase(operation)) {
            txn.start();
            for (String accountName : accountNames) {
                Account permittedAccount = _accountDao.findActiveAccount(accountName, domainId);
                if (permittedAccount != null) {
                    if (permittedAccount.getId() == caller.getId()) {
                        continue; // don't grant permission to the template owner, they implicitly have permission
                    }
                    LaunchPermissionVO existingPermission = _launchPermissionDao.findByTemplateAndAccount(id, permittedAccount.getId());
                    if (existingPermission == null) {
                        LaunchPermissionVO launchPermission = new LaunchPermissionVO(id, permittedAccount.getId());
                        _launchPermissionDao.persist(launchPermission);
                    }
                } else {
                    txn.rollback();
                    throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + ", account not found.  "
                            + "No permissions updated, please verify the account names and retry.");
                }
            }
            txn.commit();
        } else if ("remove".equalsIgnoreCase(operation)) {
            List<Long> accountIds = new ArrayList<Long>();
            for (String accountName : accountNames) {
                Account permittedAccount = _accountDao.findActiveAccount(accountName, domainId);
                if (permittedAccount != null) {
                    accountIds.add(permittedAccount.getId());
                }
            }
            _launchPermissionDao.removePermissions(id, accountIds);
        } else if ("reset".equalsIgnoreCase(operation)) {
            // do we care whether the owning account is an admin? if the
            // owner is an admin, will we still set public to false?
            updatedTemplate = _tmpltDao.createForUpdate();
            updatedTemplate.setPublicTemplate(false);
            updatedTemplate.setFeatured(false);
            _tmpltDao.update(template.getId(), updatedTemplate);
            _launchPermissionDao.removeAllPermissions(id);
        }
        return true;
    }
    
    
    private String getRandomPrivateTemplateName() {
        return UUID.randomUUID().toString();
    }
    
   
    
   

    @Override
    @DB
    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
    public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command)
            throws CloudRuntimeException {
        Long userId = UserContext.current().getCallerUserId();
        if (userId == null) {
            userId = User.UID_SYSTEM;
        }
        long templateId = command.getEntityId();
        Long volumeId = command.getVolumeId();
        Long snapshotId = command.getSnapshotId();
        VMTemplateVO privateTemplate = null;
        Long accountId = null;
        SnapshotVO snapshot = null;
        VolumeVO volume = null;

        try {
            TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
            ZoneScope scope = null;
            Long zoneId = null;
            if (snapshotId != null) {
                snapshot = _snapshotDao.findById(snapshotId);
                zoneId = snapshot.getDataCenterId();
                
            } else if (volumeId != null) {
                volume = _volumeDao.findById(volumeId);
                zoneId = volume.getDataCenterId();
            }
            scope = new ZoneScope(zoneId);
            List<DataStore> store = this.dataStoreMgr.getImageStores(scope);
            if (store.size() > 1) {
                throw new CloudRuntimeException("muliple image data store, don't know which one to use");
            }
            AsyncCallFuture<CommandResult> future = null;
            if (snapshotId != null) {
                SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
                future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
            } else if (volumeId != null) {
               VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
               future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
            } else {
                throw new CloudRuntimeException(
                        "Creating private Template need to specify snapshotId or volumeId");
            }
            
            CommandResult result = null;
            try {
                result = future.get();
                if (result.isFailed()) {
                    privateTemplate = null;
                    s_logger.debug("Failed to create template" + result.getResult());
                    throw new CloudRuntimeException("Failed to create template" + result.getResult());
                }
                
                privateTemplate = this._tmpltDao.findById(templateId);
                UsageEventVO usageEvent = new UsageEventVO(
                        EventTypes.EVENT_TEMPLATE_CREATE,
                        privateTemplate.getAccountId(),
                        zoneId,
                        privateTemplate.getId(), privateTemplate.getName(),
                        null, privateTemplate.getSourceTemplateId(),
                        privateTemplate.getSize());
                _usageEventDao.persist(usageEvent);
            } catch (InterruptedException e) {
                s_logger.debug("Failed to create template", e);
                throw new CloudRuntimeException("Failed to create template", e);
            } catch (ExecutionException e) {
                s_logger.debug("Failed to create template", e);
                throw new CloudRuntimeException("Failed to create template", e);
            }

        } finally {
            /*if (snapshot != null && snapshot.getSwiftId() != null
                    && secondaryStorageURL != null && zoneId != null
                    && accountId != null && volumeId != null) {
                _snapshotMgr.deleteSnapshotsForVolume(secondaryStorageURL,
                        zoneId, accountId, volumeId);
            }*/
            if (privateTemplate == null) {
                Transaction txn = Transaction.currentTxn();
                txn.start();
                // Remove the template record
                this._tmpltDao.expunge(templateId);

                // decrement resource count
                if (accountId != null) {
                    _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
                    _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage,
                            new Long(volume != null ? volume.getSize() : snapshot.getSize()));
                }
                txn.commit();
            }
        }

        if (privateTemplate != null) {
            return privateTemplate;
        } else {
            throw new CloudRuntimeException("Failed to create a template");
        }
    }

    private static boolean isAdmin(short accountType) {
        return ((accountType == Account.ACCOUNT_TYPE_ADMIN)
                || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)
                || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
    }
    @Override
    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true)
    public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd,
            Account templateOwner) throws ResourceAllocationException {
        Long userId = UserContext.current().getCallerUserId();

        Account caller = UserContext.current().getCaller();
        boolean isAdmin = (isAdmin(caller.getType()));

        _accountMgr.checkAccess(caller, null, true, templateOwner);

        String name = cmd.getTemplateName();
        if ((name == null) || (name.length() > 32)) {
            throw new InvalidParameterValueException(
                    "Template name cannot be null and should be less than 32 characters");
        }

        if (cmd.getTemplateTag() != null) {
            if (!_accountService.isRootAdmin(caller.getType())) {
                throw new PermissionDeniedException(
                        "Parameter templatetag can only be specified by a Root Admin, permission denied");
            }
        }

        // do some parameter defaulting
        Integer bits = cmd.getBits();
        Boolean requiresHvm = cmd.getRequiresHvm();
        Boolean passwordEnabled = cmd.isPasswordEnabled();
        Boolean isPublic = cmd.isPublic();
        Boolean featured = cmd.isFeatured();
        int bitsValue = ((bits == null) ? 64 : bits.intValue());
        boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm
                .booleanValue());
        boolean passwordEnabledValue = ((passwordEnabled == null) ? false
                : passwordEnabled.booleanValue());
        if (isPublic == null) {
            isPublic = Boolean.FALSE;
        }
        // check whether template owner can create public templates
        boolean allowPublicUserTemplates = Boolean.parseBoolean(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), templateOwner.getId()));
        if (!isAdmin && !allowPublicUserTemplates && isPublic) {
            throw new PermissionDeniedException("Failed to create template "
                    + name + ", only private templates can be created.");
        }

        Long volumeId = cmd.getVolumeId();
        Long snapshotId = cmd.getSnapshotId();
        if ((volumeId == null) && (snapshotId == null)) {
            throw new InvalidParameterValueException(
                    "Failed to create private template record, neither volume ID nor snapshot ID were specified.");
        }
        if ((volumeId != null) && (snapshotId != null)) {
            throw new InvalidParameterValueException(
                    "Failed to create private template record, please specify only one of volume ID ("
                            + volumeId
                            + ") and snapshot ID ("
                            + snapshotId
                            + ")");
        }

        HypervisorType hyperType;
        VolumeVO volume = null;
        SnapshotVO snapshot = null;
        VMTemplateVO privateTemplate = null;
        if (volumeId != null) { // create template from volume
            volume = this._volumeDao.findById(volumeId);
            if (volume == null) {
                throw new InvalidParameterValueException(
                        "Failed to create private template record, unable to find volume "
                                + volumeId);
            }
            // check permissions
            _accountMgr.checkAccess(caller, null, true, volume);

            // If private template is created from Volume, check that the volume
            // will not be active when the private template is
            // created
            if (!this.volumeMgr.volumeInactive(volume)) {
                String msg = "Unable to create private template for volume: "
                        + volume.getName()
                        + "; volume is attached to a non-stopped VM, please stop the VM first";
                if (s_logger.isInfoEnabled()) {
                    s_logger.info(msg);
                }
                throw new CloudRuntimeException(msg);
            }
            hyperType = this._volumeDao.getHypervisorType(volumeId);
        } else { // create template from snapshot
            snapshot = _snapshotDao.findById(snapshotId);
            if (snapshot == null) {
                throw new InvalidParameterValueException(
                        "Failed to create private template record, unable to find snapshot "
                                + snapshotId);
            }

            volume = this._volumeDao.findById(snapshot.getVolumeId());
            VolumeVO snapshotVolume = this._volumeDao
                    .findByIdIncludingRemoved(snapshot.getVolumeId());

            // check permissions
            _accountMgr.checkAccess(caller, null, true, snapshot);

            if (snapshot.getState() != Snapshot.State.BackedUp) {
                throw new InvalidParameterValueException("Snapshot id="
                        + snapshotId + " is not in " + Snapshot.State.BackedUp
                        + " state yet and can't be used for template creation");
            }

            /*
             * // bug #11428. Operation not supported if vmware and snapshots
             * parent volume = ROOT if(snapshot.getHypervisorType() ==
             * HypervisorType.VMware && snapshotVolume.getVolumeType() ==
             * Type.DATADISK){ throw new UnsupportedServiceException(
             * "operation not supported, snapshot with id " + snapshotId +
             * " is created from Data Disk"); }
             */

            hyperType = snapshot.getHypervisorType();
        }

        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.secondary_storage,
                new Long(volume != null ? volume.getSize() : snapshot.getSize()));

        if (!isAdmin || featured == null) {
            featured = Boolean.FALSE;
        }
        Long guestOSId = cmd.getOsTypeId();
        GuestOSVO guestOS = this._guestOSDao.findById(guestOSId);
        if (guestOS == null) {
            throw new InvalidParameterValueException("GuestOS with ID: "
                    + guestOSId + " does not exist.");
        }

        String uniqueName = Long.valueOf((userId == null) ? 1 : userId)
                .toString()
                + UUID.nameUUIDFromBytes(name.getBytes()).toString();
        Long nextTemplateId = this._tmpltDao.getNextInSequence(Long.class, "id");
        String description = cmd.getDisplayText();
        boolean isExtractable = false;
        Long sourceTemplateId = null;
        if (volume != null) {
            VMTemplateVO template = ApiDBUtils.findTemplateById(volume
                    .getTemplateId());
            isExtractable = template != null
                    && template.isExtractable()
                    && template.getTemplateType() != Storage.TemplateType.SYSTEM;
            if (template != null) {
                sourceTemplateId = template.getId();
            } else if (volume.getVolumeType() == Volume.Type.ROOT) { // vm created out
                // of blank
                // template
                UserVm userVm = ApiDBUtils.findUserVmById(volume
                        .getInstanceId());
                sourceTemplateId = userVm.getIsoId();
            }
        }
        String templateTag = cmd.getTemplateTag();
        if (templateTag != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Adding template tag: " + templateTag);
            }
        }
        privateTemplate = new VMTemplateVO(nextTemplateId, uniqueName, name,
                ImageFormat.RAW, isPublic, featured, isExtractable,
                TemplateType.USER, null, null, requiresHvmValue, bitsValue,
                templateOwner.getId(), null, description, passwordEnabledValue,
                guestOS.getId(), true, hyperType, templateTag, cmd.getDetails());
        if (sourceTemplateId != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("This template is getting created from other template, setting source template Id to: "
                        + sourceTemplateId);
            }
        }
        privateTemplate.setSourceTemplateId(sourceTemplateId);
        privateTemplate.setImageDataStoreId(1);

        VMTemplateVO template = this._tmpltDao.persist(privateTemplate);
        // Increment the number of templates
        if (template != null) {
            if (cmd.getDetails() != null) {
                this._templateDetailsDao.persist(template.getId(), cmd.getDetails());
            }

            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage,
                    new Long(volume != null ? volume.getSize() : snapshot.getSize()));
        }

        if (template != null) {
            return template;
        } else {
            throw new CloudRuntimeException("Failed to create a template");
        }

    }
    
    @Override
    public Pair<String, String> getAbsoluteIsoPath(long templateId,
            long dataCenterId) {
        String isoPath = null;

        List<HostVO> storageHosts = _resourceMgr.listAllHostsInOneZoneByType(
                Host.Type.SecondaryStorage, dataCenterId);
        if (storageHosts != null) {
            for (HostVO storageHost : storageHosts) {
                List<VMTemplateHostVO> templateHostVOs = this._tmpltHostDao
                        .listByTemplateHostStatus(
                                templateId,
                                storageHost.getId(),
                                VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
                if (templateHostVOs != null && !templateHostVOs.isEmpty()) {
                    VMTemplateHostVO tmpHostVO = templateHostVOs.get(0);
                    isoPath = storageHost.getStorageUrl() + "/"
                            + tmpHostVO.getInstallPath();
                    return new Pair<String, String>(isoPath,
                            storageHost.getStorageUrl());
                }
            }
        }
        s_logger.warn("Unable to find secondary storage in zone id="
                + dataCenterId);
        return null;
    }

    @Override
    public String getSecondaryStorageURL(long zoneId) {
        // Determine the secondary storage URL
        HostVO secondaryStorageHost = getSecondaryStorageHost(zoneId);

        if (secondaryStorageHost == null) {
            return null;
        }

        return secondaryStorageHost.getStorageUrl();
    }

    @Override
    public HostVO getSecondaryStorageHost(long zoneId, long tmpltId) {
        List<HostVO> hosts = _ssvmMgr
                .listSecondaryStorageHostsInOneZone(zoneId);
        if (hosts == null || hosts.size() == 0) {
            return null;
        }
        for (HostVO host : hosts) {
            VMTemplateHostVO tmpltHost = this._tmpltHostDao.findByHostTemplate(
                    host.getId(), tmpltId);
            if (tmpltHost != null
                    && !tmpltHost.getDestroyed()
                    && tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
                return host;
            }
        }
        return null;
    }

    @Override
    public VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId,
            boolean readyOnly) {
        List<HostVO> hosts = _ssvmMgr
                .listSecondaryStorageHostsInOneZone(zoneId);
        if (hosts == null || hosts.size() == 0) {
            return null;
        }
        VMTemplateHostVO inProgress = null;
        VMTemplateHostVO other = null;
        for (HostVO host : hosts) {
            VMTemplateHostVO tmpltHost = this._tmpltHostDao.findByHostTemplate(
                    host.getId(), tmpltId);
            if (tmpltHost != null && !tmpltHost.getDestroyed()) {
                if (tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
                    return tmpltHost;
                } else if (tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
                    inProgress = tmpltHost;
                } else {
                    other = tmpltHost;
                }
            }
        }
        if (inProgress != null) {
            return inProgress;
        }
        return other;
    }

    @Override
    public HostVO getSecondaryStorageHost(long zoneId) {
        List<HostVO> hosts = _ssvmMgr
                .listSecondaryStorageHostsInOneZone(zoneId);
        if (hosts == null || hosts.size() == 0) {
            hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId);
            if (hosts.isEmpty()) {
                return null;
            }
        }

        int size = hosts.size();
        Random rn = new Random();
        int index = rn.nextInt(size);
        return hosts.get(index);
    }

    @Override
    public List<HostVO> getSecondaryStorageHosts(long zoneId) {
        List<HostVO> hosts = _ssvmMgr
                .listSecondaryStorageHostsInOneZone(zoneId);
        if (hosts == null || hosts.size() == 0) {
            hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId);
            if (hosts.isEmpty()) {
                return new ArrayList<HostVO>();
            }
        }
        return hosts;
    }
    
    @Override
    public Long getTemplateSize(long templateId, long zoneId) {
        SearchCriteria<VMTemplateHostVO> sc = HostTemplateStatesSearch.create();
        sc.setParameters("id", templateId);
        sc.setParameters(
                "state",
                com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
        sc.setJoinParameters("host", "dcId", zoneId);
        List<VMTemplateSwiftVO> tsvs = _tmpltSwiftDao
                .listByTemplateId(templateId);
        Long size = null;
        if (tsvs != null && tsvs.size() > 0) {
            size = tsvs.get(0).getSize();
        }

        if (size == null && _s3Mgr.isS3Enabled()) {
            VMTemplateS3VO vmTemplateS3VO = _vmS3TemplateDao
                    .findOneByTemplateId(templateId);
            if (vmTemplateS3VO != null) {
                size = vmTemplateS3VO.getSize();
            }
        }

        if (size == null) {
            List<VMTemplateHostVO> sss = this.templateHostDao.search(sc, null);
            if (sss == null || sss.size() == 0) {
                throw new CloudRuntimeException("Template "
                        + templateId
                        + " has not been completely downloaded to zone "
                        + zoneId);
            }
            size = sss.get(0).getSize();
        }
        return size;
    }

}
