// 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.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.network.Networks.TrafficType;
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, long physicalNetworkId) {
    	// Check if the zone is valid
    	long zoneId = getZoneId(zone);
    	if (zoneId == -1)
    		return genReturnList("false", "Please specify a valid zone.");
    	
    	//check if physical network is valid
        long physicalNetworkDbId = checkPhysicalNetwork(physicalNetworkId);
        if (physicalNetworkId == -1)
            return genReturnList("false", "Please specify a valid physical network.");
    	
    	
    	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, physicalNetworkDbId);
            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, 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 += ", uuid";
        values += ", UUID()";
			
		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.");
		
		if (printOutput) System.out.println("Successfully saved zone.");
	}
	
	@DB
    public void savePhysicalNetwork(boolean printOutput, long id, long dcId, int vnetStart, int vnetEnd) {
        
        if (printOutput) System.out.println("Saving physical network, please wait...");
        
        String columns = null;
        String values = null;
        
        columns = "(id ";
        values = "('" + id + "'";
        
        columns += ", name ";
        values += ",'physical network'";
        
        columns += ", data_center_id ";
        values += ",'" + dcId + "'";
        
        //save vnet information
        columns += ", vnet";
        values += ",'" + vnetStart + "-" + vnetEnd + "'";
            
        columns += ", state";
        values += ", 'Enabled'";
        
        columns += ", uuid";
        values += ", UUID()";
            
        columns += ")";
        values += ")";
        
        String sql = "INSERT INTO `cloud`.`physical_network` " + columns +  " VALUES " + values;
        
        DatabaseConfig.saveSQL(sql, "Failed to save physical network 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;
        }
        
        String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id, physical_network_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.setLong(3, id);
                stmt.addBatch();
            }
            stmt.executeBatch();
        } catch (SQLException ex) {
            printError("Error creating vnet for the physical network. Please contact Cloud Support.");
        }
        
        //add default traffic types
        
        //get default Xen network labels
        String defaultXenPrivateNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Management);
        String defaultXenPublicNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Public);
        String defaultXenStorageNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Storage);
        String defaultXenGuestNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Guest);
        
        String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` (physical_network_id, traffic_type, xen_network_label) VALUES ( ?, ?, ?)";

        try {
            PreparedStatement stmt = txn.prepareAutoCloseStatement(insertTraficType);
            for (TrafficType traffic : TrafficType.values()) {
                if(traffic.equals(TrafficType.Control) || traffic.equals(TrafficType.Vpn) ||
                        traffic.equals(TrafficType.None)){
                    continue;
                }
                stmt.setLong(1, id);
                stmt.setString(2, traffic.toString());
                if(traffic.equals(TrafficType.Public)){
                    stmt.setString(3, defaultXenPublicNetworkLabel);
                }else if(traffic.equals(TrafficType.Management)){
                    stmt.setString(3, defaultXenPrivateNetworkLabel);
                }else if(traffic.equals(TrafficType.Storage)){
                    stmt.setString(3, defaultXenStorageNetworkLabel);
                }else if(traffic.equals(TrafficType.Guest)){
                    stmt.setString(3, defaultXenGuestNetworkLabel);
                }
                
                stmt.addBatch();
            }
            stmt.executeBatch();
        } catch (SQLException ex) {
            printError("Error adding default traffic types for the physical network. Please contact Cloud Support.");
        }
        
        if (printOutput) System.out.println("Successfully saved physical network.");
    }
	
    private String getDefaultXenNetworkLabel(TrafficType trafficType){
        String xenLabel = null;
        String configName = null;
        switch(trafficType){
            case Public: configName = "xen.public.network.device";
            break;
            case Guest: configName = "xen.guest.network.device";
            break;
            case Storage: configName = "xen.storage.network.device1";
            break;
            case Management: configName = "xen.private.network.device";
            break;
        }
        
        if(configName != null){
            xenLabel = getConfiguredValue(configName);
        }
        return xenLabel;
    }
    
    public static String getConfiguredValue(String configName)
    {
        return DatabaseConfig.getDatabaseValueString("SELECT value FROM `cloud`.`configuration` where name = \"" + configName + "\"","value",
                "Unable to start DB connection to read configuration. Please contact Cloud Support.");
    }
	
	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, long physicalNetworkId) {
		String sql = "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, description, network_id, physical_network_id) " + "VALUES ('" + vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange +  "','" + networkId +  "','" + physicalNetworkId + "')";
        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);
	}
	
    public static long checkPhysicalNetwork(long physicalNetworkId) {
        String selectSql = "SELECT * FROM `cloud`.`physical_network` WHERE id = \"" + physicalNetworkId + "\"";
        String errorMsg = "Could not read physicalNetwork 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;
    }
	
}
