/**
 *  Copyright (C) 2010 Cloud.com, Inc.  All rights reserved.
 * 
 * This software is licensed under the GNU General Public License v3 or later.
 * 
 * It is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package com.cloud.test;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.net.NetUtils;

public class PodZoneConfig {
	
	public static void main(String[] args) {
		PodZoneConfig config = ComponentLocator.inject(PodZoneConfig.class);
		//config.run(args);
		System.exit(0);
    }
	
	public void savePod(boolean printOutput, long id, String name, long dcId, String gateway, String cidr, int vlanStart, int vlanEnd) {
		// Check that the cidr was valid
		if (!IPRangeConfig.validCIDR(cidr)) printError("Please enter a valid CIDR for pod: " + name);
		
		// Get the individual cidrAddress and cidrSize values
		String[] cidrPair = cidr.split("\\/");
		String cidrAddress = cidrPair[0];
		String cidrSize = cidrPair[1];

		String sql = null;
		if (id != -1) sql = "INSERT INTO `cloud`.`host_pod_ref` (id, name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + id + "','" + name + "','" + dcId + "','" + gateway + "','" + cidrAddress + "','" + cidrSize + "')";
		else sql = "INSERT INTO `cloud`.`host_pod_ref` (name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + name + "','" + dcId + "','" + gateway + "','" + cidrAddress + "','" + cidrSize + "')";
			
        DatabaseConfig.saveSQL(sql, "Failed to save pod due to exception. Please contact Cloud Support.");
        
        if (printOutput) System.out.println("Successfuly saved pod.");
	}
	
	public void checkAllPodCidrSubnets() {
		Vector<Long> allZoneIDs = getAllZoneIDs();
		for (Long dcId : allZoneIDs) {
			HashMap<Long, Vector<Object>> currentPodCidrSubnets = getCurrentPodCidrSubnets(dcId.longValue());
			String result = checkPodCidrSubnets(dcId.longValue(), currentPodCidrSubnets);
			if (!result.equals("success")) printError(result);
		}
	}
	
	private String checkPodCidrSubnets(long dcId, HashMap<Long, Vector<Object>> currentPodCidrSubnets) {
		
//		DataCenterDao _dcDao = null;
//        final ComponentLocator locator = ComponentLocator.getLocator("management-server");
        
//        _dcDao = locator.getDao(DataCenterDao.class);
		// For each pod, return an error if any of the following is true:
		// 1. The pod's CIDR subnet conflicts with the guest network subnet
		// 2. The pod's CIDR subnet conflicts with the CIDR subnet of any other pod
		
		String zoneName  = PodZoneConfig.getZoneName(dcId);
		
		//get the guest network cidr and guest netmask from the zone
//		DataCenterVO dcVo = _dcDao.findById(dcId);
		
		String guestNetworkCidr = IPRangeConfig.getGuestNetworkCidr(dcId);
		
		if (guestNetworkCidr == null || guestNetworkCidr.isEmpty()) return "Please specify a valid guest cidr";
        String[] cidrTuple = guestNetworkCidr.split("\\/");
        
		String guestIpNetwork = NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]));
		long guestCidrSize = Long.parseLong(cidrTuple[1]);
        
        // Iterate through all pods in this zone
		for (Long podId : currentPodCidrSubnets.keySet()) {
			String podName;
			if (podId.longValue() == -1) podName = "newPod";
			else podName = PodZoneConfig.getPodName(podId.longValue(), dcId);
			
			Vector<Object> cidrPair = currentPodCidrSubnets.get(podId);
			String cidrAddress = (String) cidrPair.get(0);
			long cidrSize = ((Long) cidrPair.get(1)).longValue();
			
			long cidrSizeToUse = -1;
			if (cidrSize < guestCidrSize) cidrSizeToUse = cidrSize;
			else cidrSizeToUse = guestCidrSize;
			
			String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
			String guestSubnet = NetUtils.getCidrSubNet(guestIpNetwork, cidrSizeToUse);
			
			// Check that cidrSubnet does not equal guestSubnet
			if (cidrSubnet.equals(guestSubnet)) {
				if (podName.equals("newPod")) {
					return "The subnet of the pod you are adding conflicts with the subnet of the Guest IP Network. Please specify a different CIDR.";
				} else {
					return "Warning: The subnet of pod " + podName + " in zone " + zoneName + " conflicts with the subnet of the Guest IP Network. Please change either the pod's CIDR or the Guest IP Network's subnet, and re-run install-vmops-management.";
				}
			}
			
			// Iterate through the rest of the pods
			for (Long otherPodId : currentPodCidrSubnets.keySet()) {
				if (podId.equals(otherPodId)) continue;
				
				// Check that cidrSubnet does not equal otherCidrSubnet
				Vector<Object> otherCidrPair = currentPodCidrSubnets.get(otherPodId);
				String otherCidrAddress = (String) otherCidrPair.get(0);
				long otherCidrSize = ((Long) otherCidrPair.get(1)).longValue();
				
				if (cidrSize < otherCidrSize) cidrSizeToUse = cidrSize;
				else cidrSizeToUse = otherCidrSize;
				
				cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
				String otherCidrSubnet = NetUtils.getCidrSubNet(otherCidrAddress, cidrSizeToUse);
				
				if (cidrSubnet.equals(otherCidrSubnet)) {
					String otherPodName = PodZoneConfig.getPodName(otherPodId.longValue(), dcId);
					if (podName.equals("newPod")) {
						return "The subnet of the pod you are adding conflicts with the subnet of pod " + otherPodName + " in zone " + zoneName + ". Please specify a different CIDR.";
					} else {
						return "Warning: The pods " + podName + " and " + otherPodName + " in zone " + zoneName + " have conflicting CIDR subnets. Please change the CIDR of one of these pods.";
					}
				}
			}
		}
		
		return "success";
	}
	
	@DB
	protected HashMap<Long, Vector<Object>> getCurrentPodCidrSubnets(long dcId) {
		HashMap<Long, Vector<Object>> currentPodCidrSubnets = new HashMap<Long, Vector<Object>>();
		
		String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + dcId;
		Transaction txn = Transaction.currentTxn();
		try {
        	PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
        	ResultSet rs = stmt.executeQuery();
        	while (rs.next()) {
        		Long podId = rs.getLong("id");
        		String cidrAddress = rs.getString("cidr_address");
        		long cidrSize = rs.getLong("cidr_size");
        		Vector<Object> cidrPair = new Vector<Object>();
        		cidrPair.add(0, cidrAddress);
        		cidrPair.add(1, new Long(cidrSize));
        		currentPodCidrSubnets.put(podId, cidrPair);
        	}
        } catch (SQLException ex) {
        	System.out.println(ex.getMessage());
        	printError("There was an issue with reading currently saved pod CIDR subnets. Please contact Cloud Support.");
            return null;
        }
        
        return currentPodCidrSubnets;
	}
	
	public void deletePod(String name, long dcId) {
		String sql = "DELETE FROM `cloud`.`host_pod_ref` WHERE name=\"" + name + "\" AND data_center_id=\"" + dcId + "\"";
		DatabaseConfig.saveSQL(sql, "Failed to delete pod due to exception. Please contact Cloud Support.");
	}
	
	public long getVlanDbId(String zone, String vlanId) {
		long zoneId = getZoneId(zone);
		
		return DatabaseConfig.getDatabaseValueLong("SELECT * FROM `cloud`.`vlan` WHERE data_center_id=\"" + zoneId + "\" AND vlan_id =\"" + vlanId + "\"", "id",
		"Unable to start DB connection to read vlan DB id. Please contact Cloud Support.");
    }
	
	public List<String> modifyVlan(String zone, boolean add, String vlanId, String vlanGateway, String vlanNetmask, String pod, String vlanType, String ipRange, long networkId) {
    	// Check if the zone is valid
    	long zoneId = getZoneId(zone);
    	if (zoneId == -1)
    		return genReturnList("false", "Please specify a valid zone.");
    	
    	Long podId = pod!=null?getPodId(pod, zone):null;
    	if (podId != null && podId == -1)
    		return genReturnList("false", "Please specify a valid pod.");
    	
    	if (add) {
    		
    		// Make sure the gateway is valid
    		if (!NetUtils.isValidIp(vlanGateway))
    			return genReturnList("false", "Please specify a valid gateway.");
    		
    		// Make sure the netmask is valid
    		if (!NetUtils.isValidIp(vlanNetmask))
    			return genReturnList("false", "Please specify a valid netmask.");
    		
    		// Check if a vlan with the same vlanId already exists in the specified zone
    		if (getVlanDbId(zone, vlanId) != -1)
    			return genReturnList("false", "A VLAN with the specified VLAN ID already exists in zone " + zone + ".");
    		
    		/*
    		// Check if another vlan in the same zone has the same subnet
    		String newVlanSubnet = NetUtils.getSubNet(vlanGateway, vlanNetmask);
    		List<VlanVO> vlans = _vlanDao.findByZone(zoneId);
    		for (VlanVO vlan : vlans) {
    			String currentVlanSubnet = NetUtils.getSubNet(vlan.getVlanGateway(), vlan.getVlanNetmask());
    			if (newVlanSubnet.equals(currentVlanSubnet))
    				return genReturnList("false", "The VLAN with ID " + vlan.getVlanId() + " in zone " + zone + " has the same subnet. Please specify a different gateway/netmask.");
    		}
    		*/
    		
    		// Everything was fine, so persist the VLAN
    		saveVlan(zoneId, podId, vlanId, vlanGateway, vlanNetmask, vlanType, ipRange, networkId);
            if (podId != null) {
            	long vlanDbId = getVlanDbId(zone, vlanId);
            	String sql = "INSERT INTO `cloud`.`pod_vlan_map` (pod_id, vlan_db_id) " + "VALUES ('" + podId + "','" + vlanDbId  + "')";
                DatabaseConfig.saveSQL(sql, "Failed to save pod_vlan_map due to exception vlanDbId=" + vlanDbId + ", podId=" + podId + ". Please contact Cloud Support.");
            }
    		
    		return genReturnList("true", "Successfully added VLAN.");
    		
    	} else {
    		return genReturnList("false", "That operation is not suppored.");
    	}
    	
    	/*
    	else {
    		
    		// Check if a VLAN actually exists in the specified zone
    		long vlanDbId = getVlanDbId(zone, vlanId);
    		if (vlanDbId == -1)
    			return genReturnList("false", "A VLAN with ID " + vlanId + " does not exist in zone " + zone);
    		
    		// Check if there are any public IPs that are in the specified vlan.
    		List<IPAddressVO> ips = _publicIpAddressDao.listByVlanDbId(vlanDbId);
    		if (ips.size() != 0)
    			return genReturnList("false", "Please delete all IP addresses that are in VLAN " + vlanId + " before deleting the VLAN.");
    		
    		// Delete the vlan
    		_vlanDao.delete(vlanDbId);
    		
    		return genReturnList("true", "Successfully deleted VLAN.");
    	}
    	*/
    }
	
	@DB
	public void saveZone(boolean printOutput, long id, String name, String dns1, String dns2, String dns3, String dns4, int vnetStart, int vnetEnd, String guestNetworkCidr, String networkType) {
		
		if (printOutput) System.out.println("Saving zone, please wait...");
		
		String columns = null;
		String values = null;
		
		if (id != -1) {
			columns = "(id, name";
			values = "('" + id + "','" + name + "'";
		} else {
			columns = "(name";
			values = "('" + name + "'";
		}

		if (dns1 != null) {
			columns += ", dns1";
			values += ",'" + dns1 + "'";
		}
		
		if (dns2 != null) {
			columns += ", dns2";
			values += ",'" + dns2 + "'";
		}
		
		if (dns3 != null) {
			columns += ", internal_dns1";
			values += ",'" + dns3 + "'";
		}
		
		if (dns4 != null) {
			columns += ", internal_dns2";
			values += ",'" + dns4 + "'";
		}
		
		if(guestNetworkCidr != null) {
			columns += ", guest_network_cidr";
			values += ",'" + guestNetworkCidr + "'";
		}
		
		if(networkType != null) {
			columns += ", networktype";
			values += ",'" + networkType + "'";
		}
		
			
			
		columns += ")";
		values += ")";
		
		String sql = "INSERT INTO `cloud`.`data_center` " + columns +  " VALUES " + values;
		
		DatabaseConfig.saveSQL(sql, "Failed to save zone due to exception. Please contact Cloud Support.");
		
		// Hardcode the vnet range to be the full range
		int begin = 0x64;
        int end = 64000;
        
        // If vnet arguments were passed in, use them
        if (vnetStart != -1 && vnetEnd != -1) {
        	begin = vnetStart;
        	end = vnetEnd;
        }
        
        long dcId = getZoneId(name);
        String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id) VALUES ( ?, ?)";

        Transaction txn = Transaction.currentTxn();
        try {
            PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet);
            for (int i = begin; i <= end; i++) {
                stmt.setString(1, Integer.toString(i));
                stmt.setLong(2, dcId);
                stmt.addBatch();
            }
            stmt.executeBatch();
        } catch (SQLException ex) {
            printError("Error creating vnet for the data center. Please contact Cloud Support.");
        }
		
		if (printOutput) System.out.println("Successfully saved zone.");
	}
	
	public void deleteZone(String name) {
		String sql = "DELETE FROM `cloud`.`data_center` WHERE name=\"" + name + "\"";
		DatabaseConfig.saveSQL(sql, "Failed to delete zone due to exception. Please contact Cloud Support.");
	}
	
	public void saveVlan(long zoneId, Long podId, String vlanId, String vlanGateway, String vlanNetmask, String vlanType, String ipRange, long networkId) {
		String sql = "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, description, network_id) " + "VALUES ('" + vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange +  "','" + networkId + "')";
        DatabaseConfig.saveSQL(sql, "Failed to save vlan due to exception. Please contact Cloud Support.");
	}
	
	public static long getPodId(String pod, String zone) {
		long dcId = getZoneId(zone);
		String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
		String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support.";
		return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
	}
	
	public static long getPodId(String pod, long dcId) {
        String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
        String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support.";
        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
    }
	
	public static long getZoneId(String zone) {
		String selectSql = "SELECT * FROM `cloud`.`data_center` WHERE name = \"" + zone + "\"";
		String errorMsg = "Could not read zone ID from database. Please contact Cloud Support.";
		return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
	}
	
	@DB
	public Vector<Long> getAllZoneIDs() {
		Vector<Long> allZoneIDs = new Vector<Long>();
		
		String selectSql = "SELECT id FROM data_center";
		Transaction txn = Transaction.currentTxn();
		try {
        	PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
        	ResultSet rs = stmt.executeQuery();
        	while (rs.next()) {
        		Long dcId = rs.getLong("id");
        		allZoneIDs.add(dcId);
        	}
        } catch (SQLException ex) {
        	System.out.println(ex.getMessage());
        	printError("There was an issue with reading zone IDs. Please contact Cloud Support.");
            return null;
        }
        
        return allZoneIDs;
	}
	
	
	public static boolean validPod(String pod, String zone) {
		return (getPodId(pod, zone) != -1);
	}
	
	public static boolean validZone(String zone) {
		return (getZoneId(zone) != -1);
	}
	
	public static String getPodName(long podId, long dcId) {
		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`host_pod_ref` WHERE id=" + podId + " AND data_center_id=" + dcId, "name",
		"Unable to start DB connection to read pod name. Please contact Cloud Support.");
	}
	
	public static String getZoneName(long dcId) {
		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE id=" + dcId, "name",
		"Unable to start DB connection to read zone name. Please contact Cloud Support.");
	}
	
	private static void printError(String message) {
		DatabaseConfig.printError(message);
	}
	
	private List<String> genReturnList(String success, String message) {
    	List<String> returnList = new ArrayList<String>();
    	returnList.add(0, success);
    	returnList.add(1, message);
    	return returnList;
    }
	
}
