// 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.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);
	}
	
}
