// 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.
//
// Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.manager;

import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.DataCenterVO;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventVO;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.dao.HostDao;
import com.cloud.resource.ResourceManager;
import com.cloud.storage.TemplateProfile;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.template.TemplateAdapter;
import com.cloud.template.TemplateAdapterBase;
import com.cloud.template.VirtualMachineTemplate.State;
import com.cloud.user.Account;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;

import javax.inject.Inject;
import java.util.Date;
import java.util.List;

public class BareMetalTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
    @Inject
    HostDao _hostDao;
    @Inject
    ResourceManager _resourceMgr;

    @Override
    public String getName() {
        return TemplateAdapterType.BareMetal.getName();
    }

    @Override
    public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
        return super.prepare(cmd);
    }

    @Override
    public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
        throw new CloudRuntimeException("Baremetal doesn't support ISO template");
    }

    @Override
    public TemplateProfile prepare(GetUploadParamsForIsoCmd cmd) throws ResourceAllocationException {
        throw new CloudRuntimeException("Baremetal doesn't support ISO template");
    }

    private void templateCreateUsage(VMTemplateVO template, long dcId) {
        if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
            UsageEventVO usageEvent =
                new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), dcId, template.getId(), template.getName(), null,
                    template.getSourceTemplateId(), 0L);
            _usageEventDao.persist(usageEvent);
        }
    }

    @Override
    public VMTemplateVO create(TemplateProfile profile) {
        VMTemplateVO template = persistTemplate(profile, State.Active);
        List<Long> zones = profile.getZoneIdList();

        // create an entry at template_store_ref with store_id = null to represent that this template is ready for use.
        TemplateDataStoreVO vmTemplateHost =
            new TemplateDataStoreVO(null, template.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, null, template.getUrl());
        this._tmpltStoreDao.persist(vmTemplateHost);

        if (zones == null) {
            List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();
            if (dcs != null && dcs.size() > 0) {
                templateCreateUsage(template, dcs.get(0).getId());
            }
        } else {
            for (Long zoneId: zones) {
                templateCreateUsage(template, zoneId);
            }
        }

        _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
        return template;
    }

    @Override
    public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(TemplateProfile profile) {
        // TODO: support baremetal for postupload
        return null;
    }

    @Override
    public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
        throw new CloudRuntimeException("Baremetal doesn't support ISO, how the delete get here???");
    }

    @Override
    @DB
    public boolean delete(TemplateProfile profile) {
        VMTemplateVO template = profile.getTemplate();
        Long templateId = template.getId();
        boolean success = true;
        String zoneName;

        if (profile.getZoneIdList() != null && profile.getZoneIdList().size() > 1)
            throw new CloudRuntimeException("Operation is not supported for more than one zone id at a time");

        if (!template.isCrossZones() && profile.getZoneIdList() != null) {
            //get the first element in the list
            zoneName = profile.getZoneIdList().get(0).toString();
        } else {
            zoneName = "all zones";
        }

        logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
        Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
        String eventType = EventTypes.EVENT_TEMPLATE_DELETE;
        List<TemplateDataStoreVO> templateHostVOs = this._tmpltStoreDao.listByTemplate(templateId);

        for (TemplateDataStoreVO vo : templateHostVOs) {
            TemplateDataStoreVO lock = null;
            try {
                lock = _tmpltStoreDao.acquireInLockTable(vo.getId());
                if (lock == null) {
                    logger.debug("Failed to acquire lock when deleting templateDataStoreVO with ID: " + vo.getId());
                    success = false;
                    break;
                }

                vo.setDestroyed(true);
                _tmpltStoreDao.update(vo.getId(), vo);

            } finally {
                if (lock != null) {
                    _tmpltStoreDao.releaseFromLockTable(lock.getId());
                }
            }
        }

        if (profile.getZoneIdList() != null) {
            UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), profile.getZoneIdList().get(0),
                                            templateId, null);
            _usageEventDao.persist(usageEvent);

            VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(profile.getZoneIdList().get(0), templateId);

            if (templateZone != null) {
                _tmpltZoneDao.remove(templateZone.getId());
            }
        } else {
            List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();
            for (DataCenterVO dc : dcs) {
                UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), dc.getId(), templateId, null);
                _usageEventDao.persist(usageEvent);
            }
        }

        logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);

        // If there are no more non-destroyed template host entries for this template, delete it
        if (success && (_tmpltStoreDao.listByTemplate(templateId).size() == 0)) {
            long accountId = template.getAccountId();

            VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);

            try {
                if (lock == null) {
                    logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
                    success = false;
                } else if (_tmpltDao.remove(templateId)) {
                    // Decrement the number of templates and total secondary storage space used by the account.
                    _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
                    _resourceLimitMgr.recalculateResourceCount(accountId, template.getDomainId(), ResourceType.secondary_storage.getOrdinal());
                }

            } finally {
                if (lock != null) {
                    _tmpltDao.releaseFromLockTable(lock.getId());
                }
            }
            logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed.");
        }

        return success;
    }
}
