/**
 *  Copyright (C) 2011 Cloud.com, Inc.  All rights reserved.
 */

package com.cloud.network;

import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

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

import org.apache.log4j.Logger;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.DetailVO;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.host.dao.HostDao;
import com.cloud.network.Network.GuestIpType;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.AccountVO;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserStatisticsDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.Inject;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicVO;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.Nic.State;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;

@Local(value = {ExternalNetworkManager.class})
public class ExternalNetworkManagerImpl implements ExternalNetworkManager {
	public enum ExternalNetworkResourceName {
		JuniperSrx,
		F5BigIp;
	}
	
	@Inject AgentManager _agentMgr;
	@Inject NetworkManager _networkMgr;
	@Inject HostDao _hostDao;
	@Inject DataCenterDao _dcDao;
	@Inject AccountDao _accountDao;
	@Inject DomainRouterDao _routerDao;
	@Inject IPAddressDao _ipAddressDao;
	@Inject VlanDao _vlanDao;
	@Inject UserStatisticsDao _userStatsDao;
	@Inject NetworkDao _networkDao;
	@Inject PortForwardingRulesDao _portForwardingRulesDao;
	@Inject LoadBalancerDao _loadBalancerDao;
	@Inject InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
	@Inject ConfigurationDao _configDao;
	@Inject HostDetailsDao _detailsDao;
	@Inject NetworkOfferingDao _networkOfferingDao;
	@Inject NicDao _nicDao;
	
	ScheduledExecutorService _executor;
	int _externalNetworkStatsInterval;
	
	private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalNetworkManagerImpl.class);
	protected String _name;
	
	@Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
		_name = name;
		_externalNetworkStatsInterval = NumbersUtil.parseInt(_configDao.getValue(Config.RouterStatsInterval.key()), 300);
		if (_externalNetworkStatsInterval > 0){
			_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ExternalNetworkMonitor"));		
		}
    	return true;
    }
	
	@Override
    public boolean start() {
		if (_externalNetworkStatsInterval > 0){
			_executor.scheduleAtFixedRate(new ExternalNetworkUsageTask(), _externalNetworkStatsInterval, _externalNetworkStatsInterval, TimeUnit.SECONDS);
		}
    	return true;
    }

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

	@Override
    public String getName() {
    	return _name;
    }
	
	public String getExternalNetworkResourceGuid(long zoneId, ExternalNetworkResourceName name, String ip) {
		return zoneId + "-" + name + "-" + ip;
	}
	
	protected HostVO getExternalNetworkAppliance(long zoneId, Host.Type type) {
		DataCenterVO zone = _dcDao.findById(zoneId);
		if (!_networkMgr.zoneIsConfiguredForExternalNetworking(zoneId)) {
			s_logger.debug("Zone " + zone.getName() + " is not configured for external networking.");
			return null;
		} else {
			List<HostVO> externalNetworkAppliancesInZone = _hostDao.listBy(type, zoneId);
			if (externalNetworkAppliancesInZone.size() != 1) {
				return null;
			} else {
				return externalNetworkAppliancesInZone.get(0);
			}			
		}
	}
	
	public NicVO savePlaceholderNic(Network network, String ipAddress) {
		NicVO nic = new NicVO(null, null, network.getId(), null);
		nic.setIp4Address(ipAddress);
		nic.setReservationStrategy(ReservationStrategy.PlaceHolder);
		nic.setState(State.Reserved);
		return _nicDao.persist(nic);
	}
	
	protected boolean externalLoadBalancerIsInline(HostVO externalLoadBalancer) {
        DetailVO detail = _detailsDao.findDetail(externalLoadBalancer.getId(), "inline");
        return (detail != null && detail.getValue().equals("true"));
	}
	
	public int getGloballyConfiguredCidrSize() {
        try {
            String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
            return 8 + Integer.parseInt(globalVlanBits);
        } catch (Exception e) {
            throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
        }
    }
	
	public int getVlanOffset(DataCenter zone, int vlanTag) {
        if (zone.getVnet() == null) {
            throw new CloudRuntimeException("Could not find vlan range for zone " + zone.getName() + ".");
        }

        String vlanRange[] = zone.getVnet().split("-");
        int lowestVlanTag = Integer.valueOf(vlanRange[0]);
        return vlanTag - lowestVlanTag;
    }
	
protected class ExternalNetworkUsageTask implements Runnable {				
		
		public ExternalNetworkUsageTask() {		
		}
		
		private boolean updateBytes(UserStatisticsVO userStats, long newCurrentBytesSent, long newCurrentBytesReceived) {			
			long oldNetBytesSent = userStats.getNetBytesSent();
			long oldNetBytesReceived = userStats.getNetBytesReceived();
			long oldCurrentBytesSent = userStats.getCurrentBytesSent();
			long oldCurrentBytesReceived = userStats.getCurrentBytesReceived();
			String warning = "Received an external network stats byte count that was less than the stored value. Zone ID: " + userStats.getDataCenterId() + ", account ID: " + userStats.getAccountId() + ".";
						
			userStats.setCurrentBytesSent(newCurrentBytesSent);
			if (oldCurrentBytesSent > newCurrentBytesSent) {
				s_logger.warn(warning + "Stored bytes sent: " + oldCurrentBytesSent + ", new bytes sent: " + newCurrentBytesSent + ".");			
				userStats.setNetBytesSent(oldNetBytesSent + oldCurrentBytesSent);
			} 
			
			userStats.setCurrentBytesReceived(newCurrentBytesReceived);
			if (oldCurrentBytesReceived > newCurrentBytesReceived) {
				s_logger.warn(warning + "Stored bytes received: " + oldCurrentBytesReceived + ", new bytes received: " + newCurrentBytesReceived + ".");						
				userStats.setNetBytesReceived(oldNetBytesReceived + oldCurrentBytesReceived);
			} 
					
			return _userStatsDao.update(userStats.getId(), userStats);
		}
		
		/*
		 * Creates a new stats entry for the specified parameters, if one doesn't already exist.
		 */
		private boolean createStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId) {
		    HostVO host = _hostDao.findById(hostId);
			UserStatisticsVO userStats = _userStatsDao.findBy(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
			if (userStats == null) {
				return (_userStatsDao.persist(new UserStatisticsVO(accountId, zoneId, publicIp, hostId, host.getType().toString(), networkId)) != null);
			} else {
				return true;
			}
		}
		
		/*
		 * Updates an existing stats entry with new data from the specified usage answer.
		 */
		private boolean updateStatsEntry(long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer) {
			AccountVO account = _accountDao.findById(accountId);
			DataCenterVO zone = _dcDao.findById(zoneId);
			NetworkVO network = _networkDao.findById(networkId);
			HostVO host = _hostDao.findById(hostId);
			String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + host.getName();			
			
			long newCurrentBytesSent = 0;
			long newCurrentBytesReceived = 0;
			
			if (publicIp != null) {
				long[] bytesSentAndReceived = null;
				statsEntryIdentifier += ", public IP: " + publicIp;
				
				if (host.getType().equals(Host.Type.ExternalLoadBalancer) && externalLoadBalancerIsInline(host)) {
					// Look up stats for the guest IP address that's mapped to the public IP address
					InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
					
					if (mapping != null) {
						NicVO nic = _nicDao.findById(mapping.getNicId());
						String loadBalancingIpAddress = nic.getIp4Address();
						bytesSentAndReceived = answer.ipBytes.get(loadBalancingIpAddress);
						
						if (bytesSentAndReceived != null) {
							bytesSentAndReceived[0] = 0;
						}
					}
				} else {
					bytesSentAndReceived = answer.ipBytes.get(publicIp);
				}
				
				if (bytesSentAndReceived == null) {
		    		s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
		    	} else {
		        	newCurrentBytesSent += bytesSentAndReceived[0];
		        	newCurrentBytesReceived += bytesSentAndReceived[1];
		    	}
			} else {
			    URI broadcastURI = network.getBroadcastUri();
                if (broadcastURI == null) {
                    s_logger.debug("Not updating stats for guest network with ID " + network.getId() + " because the network is not implemented.");
                    return true;
                } else {
                    long vlanTag = Integer.parseInt(broadcastURI.getHost());
                    long[] bytesSentAndReceived = answer.guestVlanBytes.get(String.valueOf(vlanTag));                                   
                    
                    if (bytesSentAndReceived == null) {
                        s_logger.warn("Didn't get an external network usage answer for guest VLAN " + vlanTag);                      
                    } else {
                        newCurrentBytesSent += bytesSentAndReceived[0];
                        newCurrentBytesReceived += bytesSentAndReceived[1];
                    }
                }
			}
			
			UserStatisticsVO userStats;
			try {
				userStats = _userStatsDao.lock(accountId, zoneId, networkId, publicIp, hostId, host.getType().toString());
			} catch (Exception e) {
				s_logger.warn("Unable to find user stats entry for " + statsEntryIdentifier);
				return false;
			}
   	           			
        	if (updateBytes(userStats, newCurrentBytesSent, newCurrentBytesReceived)) {
        		s_logger.debug("Successfully updated stats for " + statsEntryIdentifier);
        		return true;
        	} else {
        		s_logger.debug("Failed to update stats for " + statsEntryIdentifier);
        		return false;
        	}
		}				
		
		private boolean createOrUpdateStatsEntry(boolean create, long accountId, long zoneId, long networkId, String publicIp, long hostId, ExternalNetworkResourceUsageAnswer answer) {
			if (create) {
				return createStatsEntry(accountId, zoneId, networkId, publicIp, hostId);
			} else {
				return updateStatsEntry(accountId, zoneId, networkId, publicIp, hostId, answer);
			}		
		}
		
		/*
		 * Creates/updates all necessary stats entries for an account and zone.
		 * Stats entries are created for source NAT IP addresses, static NAT rules, port forwarding rules, and load balancing rules
		 */
		private boolean manageStatsEntries(boolean create, long accountId, long zoneId, 
										   HostVO externalFirewall, ExternalNetworkResourceUsageAnswer firewallAnswer,
										   HostVO externalLoadBalancer, ExternalNetworkResourceUsageAnswer lbAnswer) {
			String accountErrorMsg = "Failed to update external network stats entry. Details: account ID = " + accountId;
			Transaction txn = Transaction.open(Transaction.CLOUD_DB);
			try {
				txn.start();
				
				List<NetworkVO> networksForAccount = _networkDao.listBy(accountId, zoneId, Network.GuestIpType.Virtual);
				
				for (NetworkVO network : networksForAccount) {
				    String networkErrorMsg = accountErrorMsg + ", network ID = " + network.getId();				
				    NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
				    
				    if (!offering.isSharedSourceNatService()) {
				        // Manage the entry for this network's source NAT IP address
				        List<IPAddressVO> sourceNatIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
				        if (sourceNatIps.size() == 1) {
				            String publicIp = sourceNatIps.get(0).getAddress().addr();
				            if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer)) {
	                            throw new ExecutionException(networkErrorMsg + ", source NAT IP = " + publicIp);
	                        }
				        }
				        
				        // Manage one entry for each static NAT rule in this network
	                    List<IPAddressVO> staticNatIps = _ipAddressDao.listStaticNatPublicIps(network.getId());
	                    for (IPAddressVO staticNatIp : staticNatIps) {
	                        String publicIp = staticNatIp.getAddress().addr();
	                        if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer)) {
	                            throw new ExecutionException(networkErrorMsg + ", static NAT rule public IP = " + publicIp);
	                        }  
	                    }
	                    
	                    // Manage one entry for each port forwarding rule in this network
	                    List<PortForwardingRuleVO> portForwardingRules = _portForwardingRulesDao.listByNetwork(network.getId());
	                    for (PortForwardingRuleVO portForwardingRule : portForwardingRules) {
	                        String publicIp = _networkMgr.getIp(portForwardingRule.getSourceIpAddressId()).getAddress().addr();                 
	                        if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalFirewall.getId(), firewallAnswer)) {
	                            throw new ExecutionException(networkErrorMsg + ", port forwarding rule public IP = " + publicIp);
	                        }   
	                    }
				    } else {
				        // Manage the account-wide entry for the external firewall
				        if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), null, externalFirewall.getId(), firewallAnswer)) {
	                        throw new ExecutionException(networkErrorMsg);
	                    }
				    }				    				    
				    
                    // If an external load balancer is added, manage one entry for each load balancing rule in this network
                    if (externalLoadBalancer != null && lbAnswer != null) {
                        List<LoadBalancerVO> loadBalancers = _loadBalancerDao.listByNetworkId(network.getId());
                        for (LoadBalancerVO loadBalancer : loadBalancers) {
                            String publicIp = _networkMgr.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr();               
                            if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer)) {
                                throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp);
                            }   
                        }
                    }
				    				  
				}				
				
				return txn.commit();
			} catch (Exception e) {
				s_logger.warn("Exception: ", e);
				txn.rollback();
				return false;
			} finally {
				txn.close();
			}
		}
		
		private void runExternalNetworkUsageTask() {
			s_logger.debug("External network stats collector is running...");
			for (DataCenterVO zone : _dcDao.listAll()) {				
				// Make sure the zone is configured for external networking
				if (!_networkMgr.zoneIsConfiguredForExternalNetworking(zone.getId())) {
					s_logger.debug("Zone " + zone.getName() + " is not configured for external networking, so skipping usage check.");
					continue;
				}
				
				// Only collect stats if there is an external firewall in this zone
				HostVO externalFirewall = getExternalNetworkAppliance(zone.getId(), Host.Type.ExternalFirewall);
				HostVO externalLoadBalancer = getExternalNetworkAppliance(zone.getId(), Host.Type.ExternalLoadBalancer);
				
				if (externalFirewall == null) {
					s_logger.debug("Skipping usage check for zone " + zone.getName());
					continue;
				}
				
				s_logger.debug("Collecting external network stats for zone " + zone.getName());
				
				ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
		
				// Get network stats from the external firewall
				ExternalNetworkResourceUsageAnswer firewallAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalFirewall.getId(), cmd);
				if (firewallAnswer == null || !firewallAnswer.getResult()) {
					String details = (firewallAnswer != null) ? firewallAnswer.getDetails() : "details unavailable";
					String msg = "Unable to get external firewall stats for " + zone.getName() + " due to: " + details + ".";
					s_logger.error(msg);
					continue;
				} 
											
				ExternalNetworkResourceUsageAnswer lbAnswer = null;
				if (externalLoadBalancer != null) {
				    // Get network stats from the external load balancer
				    lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
				    if (lbAnswer == null || !lbAnswer.getResult()) {
					    String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
					    String msg = "Unable to get external load balancer stats for " + zone.getName() + " due to: " + details + ".";
					    s_logger.error(msg);
				    }    				
				}
				
				List<DomainRouterVO> domainRoutersInZone = _routerDao.listByDataCenter(zone.getId());
				for (DomainRouterVO domainRouter : domainRoutersInZone) {
					long accountId = domainRouter.getAccountId();
					long zoneId = domainRouter.getDataCenterIdToDeployIn();
					
					AccountVO account = _accountDao.findById(accountId);
					if (account == null) {
						s_logger.debug("Skipping stats update for account with ID " + accountId);
						continue;
					}
					
					if (!manageStatsEntries(true, accountId, zoneId, externalFirewall, firewallAnswer, externalLoadBalancer, lbAnswer)) {
						continue;
					}
					
					manageStatsEntries(false, accountId, zoneId, externalFirewall, firewallAnswer, externalLoadBalancer, lbAnswer);
				}				
			}									
		}
		
		@Override
		public void run() {			
			GlobalLock scanLock = GlobalLock.getInternLock("ExternalNetworkManagerImpl");
            try {
                if (scanLock.lock(20)) {
                    try {
                    	runExternalNetworkUsageTask();
                    } finally {
                        scanLock.unlock();
                    }
                }
            } catch (Exception e) {
            	s_logger.warn("Problems while getting external network usage", e);
            } finally {
                scanLock.releaseRef();
            }
		}
	}
}
