// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  Citrix Systems, Inc.
// reserves all rights not expressly granted by 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 04/03/2012
package com.cloud.test;

import java.lang.reflect.Array;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Vector;

import com.cloud.network.IpAddress;
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 IPRangeConfig {
	
	public static void main(String[] args) {
		IPRangeConfig config = ComponentLocator.inject(IPRangeConfig.class);
		config.run(args);
		System.exit(0);
    }
	
	private String usage() {
		return "Usage: ./change_ip_range.sh [add|delete] [public zone | private pod zone] startIP endIP";
	}
	
	
	public void run(String[] args) {
		if (args.length < 2) {
            printError(usage());
        }
		
		String op = args[0];
		String type = args[1];
		
		if (type.equals("public")) {
			if (args.length != 4 && args.length != 5) {
                printError(usage());
            }
			String zone = args[2];
			String startIP = args[3];
			String endIP = null;
			if (args.length == 5) {
                endIP = args[4];
            }
			
			String result = checkErrors(type, op, null, zone, startIP, endIP);
			if (!result.equals("success")) {
                printError(result);
            }
			
			long zoneId = PodZoneConfig.getZoneId(zone);
			result = changeRange(op, "public", -1, zoneId, startIP, endIP, null, -1);
			result.replaceAll("<br>", "/n");
			System.out.println(result);
		} else if (type.equals("private")) {
			if (args.length != 5 && args.length != 6) {
                printError(usage());
            }
			String pod = args[2];
			String zone = args[3];;
			String startIP = args[4];
			String endIP = null;
			if (args.length == 6) {
                endIP = args[5];
            }
			
			String result = checkErrors(type, op, pod, zone, startIP, endIP);
			if (!result.equals("success")) {
                printError(result);
            }
			
			long podId = PodZoneConfig.getPodId(pod, zone);
			long zoneId = PodZoneConfig.getZoneId(zone);
			result = changeRange(op, "private", podId, zoneId, startIP, endIP, null, -1);
			result.replaceAll("<br>", "/n");
			System.out.println(result);
		} else {
			printError(usage());
		}
	}
	
	public List<String> changePublicIPRangeGUI(String op, String zone, String startIP, String endIP, long physicalNetworkId) {
		String result = checkErrors("public", op, null, zone, startIP, endIP);
		if (!result.equals("success")) {
            return DatabaseConfig.genReturnList("false", result);
        }
		
		long zoneId = PodZoneConfig.getZoneId(zone);
		result = changeRange(op, "public", -1, zoneId, startIP, endIP, null, physicalNetworkId);
		
		return DatabaseConfig.genReturnList("true", result);
	}
	
	public List<String> changePrivateIPRangeGUI(String op, String pod, String zone, String startIP, String endIP) {
		String result = checkErrors("private", op, pod, zone, startIP, endIP);
		if (!result.equals("success")) {
            return DatabaseConfig.genReturnList("false", result);
        }
		
		long podId = PodZoneConfig.getPodId(pod, zone);
		long zoneId = PodZoneConfig.getZoneId(zone);
		result = changeRange(op, "private", podId, zoneId, startIP, endIP, null, -1);
		
		return DatabaseConfig.genReturnList("true", result);
	}

	private String checkErrors(String type, String op, String pod, String zone, String startIP, String endIP) {
		if (!op.equals("add") && !op.equals("delete")) {
            return usage();
        }
		
		if (type.equals("public")) {
			// Check that the zone is valid
			if (!PodZoneConfig.validZone(zone)) {
                return "Please specify a valid zone.";
            }
		} else if (type.equals("private")) {
			// Check that the pod and zone are valid
			if (!PodZoneConfig.validZone(zone)) {
                return "Please specify a valid zone.";
            }
			if (!PodZoneConfig.validPod(pod, zone)) {
                return "Please specify a valid pod.";
            }
		}
		
		if (!validIP(startIP)) {
            return "Please specify a valid start IP";
        }
		
		if (!validOrBlankIP(endIP)) {
            return "Please specify a valid end IP";
        }
		
		// Check that the IPs that are being added are compatible with either the zone's public netmask, or the pod's CIDR
		if (type.equals("public")) {
			// String publicNetmask = getPublicNetmask(zone);
			// String publicGateway = getPublicGateway(zone);
			
			// if (publicNetmask == null) return "Please ensure that your zone's public net mask is specified";
			// if (!sameSubnet(startIP, endIP, publicNetmask)) return "Please ensure that your start IP and end IP are in the same subnet, as per the zone's netmask.";
			// if (!sameSubnet(startIP, publicGateway, publicNetmask)) return "Please ensure that your start IP is in the same subnet as your zone's gateway, as per the zone's netmask.";
			// if (!sameSubnet(endIP, publicGateway, publicNetmask)) return "Please ensure that your end IP is in the same subnet as your zone's gateway, as per the zone's netmask.";
		} else if (type.equals("private")) {
			String cidrAddress = getCidrAddress(pod, zone);
			long cidrSize = getCidrSize(pod, zone);

			if (!sameSubnetCIDR(startIP, endIP, cidrSize)) {
                return "Please ensure that your start IP and end IP are in the same subnet, as per the pod's CIDR size.";
            }
			if (!sameSubnetCIDR(startIP, cidrAddress, cidrSize)) {
                return "Please ensure that your start IP is in the same subnet as the pod's CIDR address.";
            }
			if (!sameSubnetCIDR(endIP, cidrAddress, cidrSize)) {
                return "Please ensure that your end IP is in the same subnet as the pod's CIDR address.";
            }
		}
		
		if (!validIPRange(startIP, endIP)) {
            return "Please specify a valid IP range.";
        }
		
		return "success";
	}
	
	private String genChangeRangeSuccessString(List<String> problemIPs, String op) {
		if (problemIPs == null) {
            return "";
        }
		
		if (problemIPs.size() == 0) {
			if (op.equals("add")) {
                return "Successfully added all IPs in the specified range.";
            } else if (op.equals("delete")) {
                return "Successfully deleted all IPs in the specified range.";
            } else {
                return "";
            }
		} else {
			String successString = "";
			if (op.equals("add")) {
                successString += "Failed to add the following IPs, because they are already in the database: <br><br>";
            } else if (op.equals("delete")) {
                successString += "Failed to delete the following IPs, because they are in use: <br><br>";
            }
			
			for (int i = 0; i < problemIPs.size(); i++) {
				successString += problemIPs.get(i);
				if (i != (problemIPs.size() - 1)) {
                    successString += ", ";
                }
			}
			
			successString += "<br><br>";
			
			if (op.equals("add")) {
                successString += "Successfully added all other IPs in the specified range.";
            } else if (op.equals("delete")) {
                successString += "Successfully deleted all other IPs in the specified range.";
            }
			
			return successString;
		}
	}
	
	private String changeRange(String op, String type, long podId, long zoneId, String startIP, String endIP, Long networkId, long physicalNetworkId) {
		
		// Go through all the IPs and add or delete them
		List<String> problemIPs = null;
		if (op.equals("add")) {
			problemIPs = saveIPRange(type, podId, zoneId, 1, startIP, endIP, networkId, physicalNetworkId);
		} else if (op.equals("delete")) {
			problemIPs = deleteIPRange(type, podId, zoneId, 1, startIP, endIP);
		}
		
		if (problemIPs == null) {
            return null;
        } else {
            return genChangeRangeSuccessString(problemIPs, op);
        }
	}
	
	private String genSuccessString(Vector<String> problemIPs, String op) {
		if (problemIPs == null) {
            return "";
        }
		
		if (problemIPs.size() == 0) {
			if (op.equals("add")) {
                return "Successfully added all IPs in the specified range.";
            } else if (op.equals("delete")) {
                return "Successfully deleted all IPs in the specified range.";
            } else {
                return "";
            }
		} else {
			String successString = "";
			if (op.equals("add")) {
                successString += "Failed to add the following IPs, because they are already in the database: <br><br>";
            } else if (op.equals("delete")) {
                successString += "Failed to delete the following IPs, because they are in use: <br><br>";
            }
			
			for (int i = 0; i < problemIPs.size(); i++) {
				successString += problemIPs.elementAt(i);
				if (i != (problemIPs.size() - 1)) {
                    successString += ", ";
                }
			}
			
			successString += "<br><br>";
			
			if (op.equals("add")) {
                successString += "Successfully added all other IPs in the specified range.";
            } else if (op.equals("delete")) {
                successString += "Successfully deleted all other IPs in the specified range.";
            }
			
			return successString;
		}
	}
	
	public static String getCidrAddress(String pod, String zone) {
		long dcId = PodZoneConfig.getZoneId(zone);
		String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
		String errorMsg = "Could not read CIDR address for pod/zone: " + pod + "/" + zone + " from database. Please contact Cloud Support.";
		return DatabaseConfig.getDatabaseValueString(selectSql, "cidr_address", errorMsg);
	}
	
	public static long getCidrSize(String pod, String zone) {
		long dcId = PodZoneConfig.getZoneId(zone);
		String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
		String errorMsg = "Could not read CIDR address for pod/zone: " + pod + "/" + zone + " from database. Please contact Cloud Support.";
		return DatabaseConfig.getDatabaseValueLong(selectSql, "cidr_size", errorMsg);
	}

	@DB
	protected Vector<String> deleteIPRange(String type, long podId, long zoneId, long vlanDbId, String startIP, String endIP) {
    	long startIPLong = NetUtils.ip2Long(startIP);
    	long endIPLong = startIPLong;
    	if (endIP != null) {
            endIPLong = NetUtils.ip2Long(endIP);
        }
 
    	Transaction txn = Transaction.currentTxn();
    	Vector<String> problemIPs = null;
    	if (type.equals("public")) {
            problemIPs = deletePublicIPRange(txn, startIPLong, endIPLong, vlanDbId);
        } else if (type.equals("private")) {
            problemIPs = deletePrivateIPRange(txn, startIPLong, endIPLong, podId, zoneId);
        }
    	
    	return problemIPs;
    }
	
	private Vector<String> deletePublicIPRange(Transaction txn, long startIP, long endIP, long vlanDbId) {
		String deleteSql = "DELETE FROM `cloud`.`user_ip_address` WHERE public_ip_address = ? AND vlan_id = ?";
		String isPublicIPAllocatedSelectSql = "SELECT * FROM `cloud`.`user_ip_address` WHERE public_ip_address = ? AND vlan_id = ?";
		
		Vector<String> problemIPs = new Vector<String>();
		PreparedStatement stmt = null;
		PreparedStatement isAllocatedStmt = null;
		
		Connection conn = null;
		try {
			conn = txn.getConnection();
			stmt = conn.prepareStatement(deleteSql);
			isAllocatedStmt = conn.prepareStatement(isPublicIPAllocatedSelectSql);
		} catch (SQLException e) {
			return null;
		}
		
		while (startIP <= endIP) {
			if (!isPublicIPAllocated(startIP, vlanDbId, isAllocatedStmt)) {
				try {
					stmt.clearParameters();
					stmt.setLong(1, startIP);
					stmt.setLong(2, vlanDbId);
					stmt.executeUpdate();
				} catch (Exception ex) {
				}
			} else {
				problemIPs.add(NetUtils.long2Ip(startIP));
			}
			startIP += 1;
		}
			
        return problemIPs;
	}
	
	private Vector<String> deletePrivateIPRange(Transaction txn, long startIP, long endIP, long podId, long zoneId) {
		String deleteSql = "DELETE FROM `cloud`.`op_dc_ip_address_alloc` WHERE ip_address = ? AND pod_id = ? AND data_center_id = ?";
		String isPrivateIPAllocatedSelectSql = "SELECT * FROM `cloud`.`op_dc_ip_address_alloc` WHERE ip_address = ? AND data_center_id = ? AND pod_id = ?";
		
		Vector<String> problemIPs = new Vector<String>();
		PreparedStatement stmt = null;
		PreparedStatement isAllocatedStmt = null;
				
		Connection conn = null;
		try {
			conn = txn.getConnection();
			stmt = conn.prepareStatement(deleteSql);
			isAllocatedStmt = conn.prepareStatement(isPrivateIPAllocatedSelectSql);
		} catch (SQLException e) {
			System.out.println("Exception: " + e.getMessage());
			printError("Unable to start DB connection to delete private IPs. Please contact Cloud Support.");
		}
		
		while (startIP <= endIP) {
			if (!isPrivateIPAllocated(NetUtils.long2Ip(startIP), podId, zoneId, isAllocatedStmt)) {
				try {
					stmt.clearParameters();
					stmt.setString(1, NetUtils.long2Ip(startIP));
					stmt.setLong(2, podId);
					stmt.setLong(3, zoneId);
					stmt.executeUpdate();
				} catch (Exception ex) {
				}
			} else {
				problemIPs.add(NetUtils.long2Ip(startIP));
			}
        	startIP += 1;
		}

        return problemIPs;
	}
	
	private boolean isPublicIPAllocated(long ip, long vlanDbId, PreparedStatement stmt) {
		try {
        	stmt.clearParameters();
        	stmt.setLong(1, ip);
        	stmt.setLong(2, vlanDbId);
        	ResultSet rs = stmt.executeQuery();
        	if (rs.next()) {
                return (rs.getString("allocated") != null);
            } else {
                return false;
            }
        } catch (SQLException ex) {
        	System.out.println(ex.getMessage());
            return true;
        }
	}
	
	private boolean isPrivateIPAllocated(String ip, long podId, long zoneId, PreparedStatement stmt) {
		try {
			stmt.clearParameters();
        	stmt.setString(1, ip);
        	stmt.setLong(2, zoneId);
        	stmt.setLong(3, podId);
        	ResultSet rs = stmt.executeQuery();
        	if (rs.next()) {
                return (rs.getString("taken") != null);
            } else {
                return false;
            }
        } catch (SQLException ex) {
        	System.out.println(ex.getMessage());
            return true;
        }
	}
	
	@DB
	public List<String> saveIPRange(String type, long podId, long zoneId, long vlanDbId, String startIP, String endIP, Long sourceNetworkId, long physicalNetworkId) {
    	long startIPLong = NetUtils.ip2Long(startIP);
    	long endIPLong = startIPLong;
    	if (endIP != null) {
            endIPLong = NetUtils.ip2Long(endIP);
        }
    	
    	Transaction txn = Transaction.currentTxn();
    	List<String> problemIPs = null;
    	
    	if (type.equals("public")) {
            problemIPs = savePublicIPRange(txn, startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkId, physicalNetworkId);
        } else if (type.equals("private")) {
            problemIPs = savePrivateIPRange(txn, startIPLong, endIPLong, podId, zoneId);
        }
    	
    	String[] linkLocalIps = NetUtils.getLinkLocalIPRange(10);
    	long startLinkLocalIp = NetUtils.ip2Long(linkLocalIps[0]);
    	long endLinkLocalIp = NetUtils.ip2Long(linkLocalIps[1]);
    	
    	saveLinkLocalPrivateIPRange(txn, startLinkLocalIp,  endLinkLocalIp, podId, zoneId);
    	
    	return problemIPs;
    }
	
	public Vector<String> savePublicIPRange(Transaction txn, long startIP, long endIP, long zoneId, long vlanDbId, Long sourceNetworkId, long physicalNetworkId) {
		String insertSql = "INSERT INTO `cloud`.`user_ip_address` (public_ip_address, data_center_id, vlan_db_id, mac_address, source_network_id, physical_network_id) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?)";
		String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?";
		Vector<String> problemIPs = new Vector<String>();
		PreparedStatement stmt = null;
		
		Connection conn = null;
		try {
			conn = txn.getConnection();
		} catch (SQLException e) {
			return null;
		}
        
        while (startIP <= endIP) {
            try {
    		stmt = conn.prepareStatement(insertSql);
    		stmt.setString(1, NetUtils.long2Ip(startIP));
    		stmt.setLong(2, zoneId);
    		stmt.setLong(3, vlanDbId);
    		stmt.setLong(4, zoneId);
    		stmt.setLong(5, sourceNetworkId);
    		stmt.setLong(6, physicalNetworkId);
    		stmt.executeUpdate();
    		stmt.close();
    		stmt = conn.prepareStatement(updateSql);
    		stmt.setLong(1, zoneId);
            stmt.executeUpdate();
            stmt.close();
            } catch (Exception ex) {
                problemIPs.add(NetUtils.long2Ip(startIP));
            }
            startIP++;
        }
        
        return problemIPs;
	}
	
	public List<String> savePrivateIPRange(Transaction txn, long startIP, long endIP, long podId, long zoneId) {
		String insertSql = "INSERT INTO `cloud`.`op_dc_ip_address_alloc` (ip_address, data_center_id, pod_id, mac_address) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?))";
        String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?";
		Vector<String> problemIPs = new Vector<String>();
		
        try {
            Connection conn = null;
            conn = txn.getConnection();
            while (startIP <= endIP) {
                try {
                    PreparedStatement stmt = conn.prepareStatement(insertSql);
            		stmt.setString(1, NetUtils.long2Ip(startIP));
            		stmt.setLong(2, zoneId);
            		stmt.setLong(3, podId);
            		stmt.setLong(4, zoneId);
            		stmt.executeUpdate();
            		stmt.close();
                    stmt = conn.prepareStatement(updateSql);
                    stmt.setLong(1, zoneId);
                    stmt.executeUpdate();
                    stmt.close();
                } catch (Exception e) {
                    problemIPs.add(NetUtils.long2Ip(startIP));
                }
                startIP++;
            }
        } catch (Exception ex) {
            System.out.print(ex.getMessage());
            ex.printStackTrace();
        } 
        
        return problemIPs;
	}
	
	private Vector<String> saveLinkLocalPrivateIPRange(Transaction txn, long startIP, long endIP, long podId, long zoneId) {
		String insertSql = "INSERT INTO `cloud`.`op_dc_link_local_ip_address_alloc` (ip_address, data_center_id, pod_id) VALUES (?, ?, ?)";
		Vector<String> problemIPs = new Vector<String>();
		
		Connection conn = null;
		try {
			conn = txn.getConnection();
		} catch (SQLException e) {
			System.out.println("Exception: " + e.getMessage());
			printError("Unable to start DB connection to save private IPs. Please contact Cloud Support.");
		}
		
        try {
            long start = startIP;
            PreparedStatement stmt = conn.prepareStatement(insertSql);
            while (startIP <= endIP) {
        		stmt.setString(1, NetUtils.long2Ip(startIP++));
        		stmt.setLong(2, zoneId);
        		stmt.setLong(3, podId);
        		stmt.addBatch();
            }
            int[] results = stmt.executeBatch();
            for (int i = 0; i < results.length; i += 2) {
                if (results[i] == Statement.EXECUTE_FAILED) {
                    problemIPs.add(NetUtils.long2Ip(start + (i / 2)));
                }
            }
            stmt.close();
	    } catch (Exception ex) {
        }
        
        return problemIPs;
	}
	
	public static String getPublicNetmask(String zone) {
		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE name = \"" + zone + "\"", "netmask",
								"Unable to start DB connection to read public netmask. Please contact Cloud Support.");
	}
		
	public static String getPublicGateway(String zone) {
		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE name = \"" + zone + "\"", "gateway",
								"Unable to start DB connection to read public gateway. Please contact Cloud Support.");
	}
	
	public static String getGuestNetworkCidr(Long zoneId)
	{
		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE id = \"" + zoneId + "\"","guest_network_cidr",
				"Unable to start DB connection to read guest cidr network. Please contact Cloud Support.");
	}
	
//	public static String getGuestIpNetwork() {
//		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.ip.network\"", "value",
//		"Unable to start DB connection to read guest IP network. Please contact Cloud Support.");
//	}
//	
//	public static String getGuestNetmask() {
//		return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.netmask\"", "value",
//		"Unable to start DB connection to read guest netmask. Please contact Cloud Support.");
//	}
	
//	public static String getGuestSubnet() {
//		String guestIpNetwork = getGuestIpNetwork();
//		String guestNetmask = getGuestNetmask();
//		
//		if (guestIpNetwork == null || guestIpNetwork.isEmpty()) printError("Please enter a valid guest IP network address.");
//		if (guestNetmask == null || guestNetmask.isEmpty()) printError("Please enter a valid guest IP network netmask");
//		
//		return NetUtils.getSubNet(guestIpNetwork, guestNetmask);
//	}

//	public static long getGuestCidrSize() {
//		String guestNetmask = getGuestNetmask();
//		return NetUtils.getCidrSize(guestNetmask);
//	}
	
	public static boolean validCIDR(final String cidr) {
		if (cidr == null || cidr.isEmpty()) {
            return false;
        }
        String[] cidrPair = cidr.split("\\/");
        if (cidrPair.length != 2) {
            return false;
        }
        String cidrAddress = cidrPair[0];
        String cidrSize = cidrPair[1];
        if (!validIP(cidrAddress)) {
            return false;
        }
        int cidrSizeNum = -1;
        
        try {
        	cidrSizeNum = Integer.parseInt(cidrSize);
        } catch (Exception e) {
        	return false;
        }
        
        if (cidrSizeNum < 1 || cidrSizeNum > 32) {
            return false;
        }
        
        return true;
	}
	
	public static boolean validOrBlankIP(final String ip) {
	    if (ip == null || ip.isEmpty()) {
            return true;
        }
	    return validIP(ip);
	}
	    
	public static boolean validIP(final String ip) {
		final String[] ipAsList = ip.split("\\.");
		
	    // The IP address must have four octets
	    if (Array.getLength(ipAsList) != 4) {
	    	return false;
	    }
	    
	    for (int i = 0; i < 4; i++) {
	    	// Each octet must be an integer
	    	final String octetString = ipAsList[i];
	    	int octet;
	    	try {
	    		octet = Integer.parseInt(octetString);
	    	} catch(final Exception e) {
	    		return false;
	   		}
	    	// Each octet must be between 0 and 255, inclusive
	    	if (octet < 0 || octet > 255) {
                return false;
            }

	    	// Each octetString must have between 1 and 3 characters
	    	if (octetString.length() < 1 || octetString.length() > 3) {
                return false;
            }
	   		
	   	}
	    
	   	// IP is good, return true
		return true;
	}
	   
    public static boolean validIPRange(String startIP, String endIP) {
    	if (endIP == null || endIP.isEmpty()) {
            return true;
        }
    	
    	long startIPLong = NetUtils.ip2Long(startIP);
    	long endIPLong =  NetUtils.ip2Long(endIP);
	   	return (startIPLong < endIPLong);
    }
    
    public static boolean sameSubnet(final String ip1, final String ip2, final String netmask) {
    	if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) {
            return true;
        }
    	String subnet1 = NetUtils.getSubNet(ip1, netmask);
    	String subnet2 = NetUtils.getSubNet(ip2, netmask);
    	
    	return (subnet1.equals(subnet2));
    }
    
    public static boolean sameSubnetCIDR(final String ip1, final String ip2, final long cidrSize) {
    	if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) {
            return true;
        }
    	String subnet1 = NetUtils.getCidrSubNet(ip1, cidrSize);
    	String subnet2 = NetUtils.getCidrSubNet(ip2, cidrSize);
    	
    	return (subnet1.equals(subnet2));
    }
    
	private static void printError(String message) {
		DatabaseConfig.printError(message);
	}
	
}
