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

import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

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.StartupCommand;
import com.cloud.agent.api.StartupExternalDhcpCommand;
import com.cloud.agent.api.routing.DhcpEntryCommand;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;

@Component
@Local(value = {ExternalDhcpManager.class})
public class ExternalDhcpManagerImpl extends ManagerBase implements ExternalDhcpManager, ResourceStateAdapter {
	private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalDhcpManagerImpl.class);
	@Inject DataCenterDao _dcDao;
	@Inject HostDao _hostDao;
	@Inject AgentManager _agentMgr;
	@Inject HostPodDao _podDao;
	@Inject UserVmDao _userVmDao;
	@Inject ResourceManager _resourceMgr;
	@Inject NicDao _nicDao;
	
	@Override
	public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
		_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 String getDhcpServerGuid(String zoneId, String name, String ip) {
		return zoneId + "-" + name + "-" + ip;
	}
	
	
	@Override @DB
	public Host addDhcpServer(Long zoneId, Long podId, String type, String url, String username, String password) {	
		DataCenterVO zone = _dcDao.findById(zoneId);
		if (zone == null) {
			throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId);
		} 
		
		HostPodVO pod = _podDao.findById(podId);
		if (pod == null) {
			throw new InvalidParameterValueException("Could not find pod with ID: " + podId);
		} 
		
		List<HostVO> dhcps = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.ExternalDhcp, null, podId, zoneId);
		if (dhcps.size() != 0) {
			throw new InvalidParameterValueException("Already had a DHCP server in Pod: " + podId + " zone: " + zoneId);
		}
		
		
		String ipAddress = url;
		String guid = getDhcpServerGuid(Long.toString(zoneId) + "-" + Long.toString(podId), "ExternalDhcp", ipAddress);
		Map params = new HashMap<String, String>();
		params.put("type", type);
		params.put("zone", Long.toString(zoneId));
		params.put("pod", podId.toString());
		params.put("ip", ipAddress);
		params.put("username", username);
		params.put("password", password);
		params.put("guid", guid);
		params.put("pod", Long.toString(podId));
		params.put("gateway", pod.getGateway());
		String dns = zone.getDns1();
		if (dns == null) {
			dns = zone.getDns2();
		}
		params.put("dns", dns);
		
		ServerResource resource = null;
		try {
			if (type.equalsIgnoreCase(DhcpServerType.Dnsmasq.getName())) {
				resource = new DnsmasqResource();
				resource.configure("Dnsmasq resource", params);
			} else if (type.equalsIgnoreCase(DhcpServerType.Dhcpd.getName())) {
				resource = new DhcpdResource();
				resource.configure("Dhcpd resource", params);
			} else {
				throw new CloudRuntimeException("Unsupport DHCP server " + type);
			}
		} catch (Exception e) {
			s_logger.debug(e);
			throw new CloudRuntimeException(e.getMessage());
		}
		
		Host dhcpServer = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalDhcp, params);
		if (dhcpServer == null) {
			throw new CloudRuntimeException("Cannot add external Dhcp server as a host");
		}
		
		Transaction txn = Transaction.currentTxn();
        txn.start();
        pod.setExternalDhcp(true);
        _podDao.update(pod.getId(), pod);
        txn.commit();
		return dhcpServer;
	}
	
	@Override
	public DhcpServerResponse getApiResponse(Host dhcpServer) {
		DhcpServerResponse response = new DhcpServerResponse();
		response.setId(dhcpServer.getUuid());
		return response;
	}

	private void prepareBareMetalDhcpEntry(NicProfile nic, DhcpEntryCommand cmd) {
		Long vmId = nic.getVmId();
		UserVmVO vm = _userVmDao.findById(vmId);
		if (vm == null || vm.getHypervisorType() != HypervisorType.BareMetal) {
			s_logger.debug("VM " + vmId + " is not baremetal machine, skip preparing baremetal DHCP entry");
			return;
		}
		
		List<HostVO> servers = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.PxeServer, null, vm.getPodIdToDeployIn(), vm.getDataCenterId());
		if (servers.size() != 1) {
			throw new CloudRuntimeException("Wrong number of PXE server found in zone " + vm.getDataCenterId()
					+ " Pod " + vm.getPodIdToDeployIn() + ", number is " + servers.size());
		}
		HostVO pxeServer = servers.get(0);
		cmd.setNextServer(pxeServer.getPrivateIpAddress());
		s_logger.debug("Set next-server to " + pxeServer.getPrivateIpAddress() + " for VM " + vm.getId());
	}
	
	@Override
	public boolean addVirtualMachineIntoNetwork(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> profile, DeployDestination dest,
			ReservationContext context) throws ResourceUnavailableException {
		Long zoneId = profile.getVirtualMachine().getDataCenterId();
		Long podId = profile.getVirtualMachine().getPodIdToDeployIn();
		List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHosts(Type.ExternalDhcp, null, podId, zoneId);
		if (hosts.size() == 0) {
			throw new CloudRuntimeException("No external Dhcp found in zone " + zoneId + " pod " + podId);
		}
		
		if (hosts.size() > 1) {
			throw new CloudRuntimeException("Something wrong, more than 1 external Dhcp found in zone " + zoneId + " pod " + podId);
		}
		
		HostVO h = hosts.get(0);
		String dns = nic.getDns1();
		if (dns == null) {
			dns = nic.getDns2();
		}
		DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), profile.getVirtualMachine().getHostName(), null, dns, nic.getGateway(), null);
		String errMsg = String.format("Set dhcp entry on external DHCP %1$s failed(ip=%2$s, mac=%3$s, vmname=%4$s)",
				h.getPrivateIpAddress(), nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName());
		//prepareBareMetalDhcpEntry(nic, dhcpCommand);
		try {
			Answer ans = _agentMgr.send(h.getId(), dhcpCommand);
			if (ans.getResult()) {
				s_logger.debug(String.format("Set dhcp entry on external DHCP %1$s successfully(ip=%2$s, mac=%3$s, vmname=%4$s)",
						h.getPrivateIpAddress(), nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName()));
				return true;
			} else {
				s_logger.debug(errMsg + " " + ans.getDetails());
				throw new ResourceUnavailableException(errMsg, DataCenter.class, zoneId);
			}
		} catch (Exception e) {
			s_logger.debug(errMsg, e);
			throw new ResourceUnavailableException(errMsg + e.getMessage(), DataCenter.class, zoneId);
		}
	}

	@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 StartupExternalDhcpCommand)) {
            return null;
        }
        
        host.setType(Host.Type.ExternalDhcp);
        return host;
    }

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