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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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

import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd;
import org.apache.cloudstack.api.AddBaremetalPxeCmd;
import org.apache.cloudstack.api.AddBaremetalPxePingServerCmd;
import org.apache.cloudstack.api.ListBaremetalPxeServersCmd;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupPxeServerCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.baremetal.database.BaremetalPxeVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;

public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxeManager, ResourceStateAdapter {
    private static final org.apache.log4j.Logger s_logger = Logger.getLogger(BaremetalPxeManagerImpl.class);
    @Inject
    DataCenterDao _dcDao;
    @Inject
    HostDao _hostDao;
    @Inject
    AgentManager _agentMgr;
    @Inject
    ResourceManager _resourceMgr;
    @Inject
    List<BaremetalPxeService> _services;
    @Inject
    UserVmDao _vmDao;
    @Inject
    ServiceOfferingDao _serviceOfferingDao;
    @Inject
    NicDao _nicDao;
    @Inject
    ConfigurationDao _configDao;
    @Inject
    PhysicalNetworkDao _phynwDao;
    @Inject
    NetworkModel _ntwkModel;

    @Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
        setName(name);
        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
        return true;
    }

    @Override
    public boolean start() {
        return true;
    }

    @Override
    public boolean stop() {
        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
        return true;
    }

    protected BaremetalPxeService getServiceByType(String type) {
        for (BaremetalPxeService service : _services) {
            if (service.getPxeServiceType().equals(type)) {
                return service;
            }
        }

        throw new CloudRuntimeException("Cannot find PXE service for " + type);
    }

    @Override
    public boolean prepare(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) {
        //TODO: select type from template
        BaremetalPxeType type = BaremetalPxeType.KICK_START;
        return getServiceByType(type.toString()).prepare(profile, nic, network, dest, context);
    }

    @Override
    public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl) {
        //TODO: select type from template
        BaremetalPxeType type = BaremetalPxeType.PING;
        return getServiceByType(type.toString()).prepareCreateTemplate(pxeServerId, vm, templateUrl);
    }

    @Override
    public BaremetalPxeType getPxeServerType(HostVO host) {
        if (host.getResource().equalsIgnoreCase(BaremetalPingPxeResource.class.getName())) {
            return BaremetalPxeType.PING;
        } else {
            throw new CloudRuntimeException("Unkown PXE server resource " + host.getResource());
        }
    }

    @Override
    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
        if (!(startup[0] instanceof StartupPxeServerCommand)) {
            return null;
        }

        host.setType(Host.Type.BaremetalPxe);
        return host;
    }

    @Override
    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd) {
        return getServiceByType(cmd.getDeviceType()).addPxeServer(cmd);
    }

    @Override
    public BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo) {
        return getServiceByType(vo.getDeviceType()).getApiResponse(vo);
    }

    @Override
    public List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxeServersCmd cmd) {
        return getServiceByType(BaremetalPxeType.KICK_START.toString()).listPxeServers(cmd);
    }

    @Override
    public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) {
        UserVmVO vm = _vmDao.findById(profile.getVirtualMachine().getId());
        _vmDao.loadDetails(vm);

        String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
        String zoneName = _dcDao.findById(vm.getDataCenterId()).getName();
        NicVO nvo = _nicDao.findById(nic.getId());
        VmDataCommand cmd = new VmDataCommand(nvo.getIPv4Address(), vm.getInstanceName(), _ntwkModel.getExecuteInSeqNtwkElmtCmd());
        // if you add new metadata files, also edit systemvm/patches/debian/config/var/www/html/latest/.htaccess
        cmd.addVmData("userdata", "user-data", vm.getUserData());
        cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
        cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
        cmd.addVmData("metadata", "local-ipv4", nic.getIPv4Address());
        cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
        cmd.addVmData("metadata", "public-ipv4", nic.getIPv4Address());
        cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
        cmd.addVmData("metadata", "instance-id", String.valueOf(vm.getUuid()));
        cmd.addVmData("metadata", "vm-id", String.valueOf(vm.getInstanceName()));
        cmd.addVmData("metadata", "public-keys", null);
        String cloudIdentifier = _configDao.getValue("cloud.identifier");
        if (cloudIdentifier == null) {
            cloudIdentifier = "";
        } else {
            cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
        }
        cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier);

        List<PhysicalNetworkVO> phys = _phynwDao.listByZone(vm.getDataCenterId());
        if (phys.isEmpty()) {
            throw new CloudRuntimeException(String.format("Cannot find physical network in zone %s", vm.getDataCenterId()));
        }
        if (phys.size() > 1) {
            throw new CloudRuntimeException(String.format("Baremetal only supports one physical network in zone, but zone %s has %s physical networks",
                vm.getDataCenterId(), phys.size()));
        }
        PhysicalNetworkVO phy = phys.get(0);

        QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
        //TODO: handle both kickstart and PING
        //sc.addAnd(sc.getEntity().getPodId(), Op.EQ, vm.getPodIdToDeployIn());
        sc.and(sc.entity().getPhysicalNetworkId(), Op.EQ, phy.getId());
        BaremetalPxeVO pxeVo = sc.find();
        if (pxeVo == null) {
            throw new CloudRuntimeException("No PXE server found in pod: " + vm.getPodIdToDeployIn() + ", you need to add it before starting VM");
        }

        try {
            Answer ans = _agentMgr.send(pxeVo.getHostId(), cmd);
            if (!ans.getResult()) {
                s_logger.debug(String.format("Add userdata to vm:%s failed because %s", vm.getInstanceName(), ans.getDetails()));
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            s_logger.debug(String.format("Add userdata to vm:%s failed", vm.getInstanceName()), e);
            return false;
        }
    }

    @Override
    public List<Class<?>> getCommands() {
        List<Class<?>> cmds = new ArrayList<Class<?>>();
        cmds.add(AddBaremetalKickStartPxeCmd.class);
        cmds.add(AddBaremetalPxePingServerCmd.class);
        cmds.add(ListBaremetalPxeServersCmd.class);
        return cmds;
    }
}
