// 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.UUID;
import java.util.Vector;

import com.cloud.utils.component.ComponentContext;
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 = ComponentContext.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, uuid) 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.setString(7, UUID.randomUUID().toString());
                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);
    }

}
