/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed 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 org.onosproject.ospf.protocol.util;

import org.onosproject.ospf.controller.OspfLsa;
import org.onosproject.ospf.controller.OspfLsaType;
import org.onosproject.ospf.protocol.lsa.types.AsbrSummaryLsa;
import org.onosproject.ospf.protocol.lsa.types.ExternalLsa;
import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa11;
import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa9;
import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
import org.onosproject.ospf.protocol.lsa.types.SummaryLsa;
import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
import org.onosproject.ospf.protocol.ospfpacket.types.HelloPacket;
import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;

import java.util.Arrays;

/**
 * Calculates checksum for different types of OSPF packets.
 */
public class ChecksumCalculator {

    /**
     * Converts given string to sixteen bits integer.
     * If hexasum is more than 16 bit value, needs to be reduced to 16 bit value.
     *
     * @param strToConvert hexasum value to convert
     * @return 16 bit integer value
     */
    public static int convertToSixteenBits(String strToConvert) {
        StringBuilder sb = new StringBuilder(strToConvert);
        sb = sb.reverse();
        StringBuilder s1 = new StringBuilder(sb.substring(0, 4));
        s1 = s1.reverse();
        StringBuilder s2 = new StringBuilder(sb.substring(4, sb.length()));
        s2 = s2.reverse();
        int num = Integer.parseInt(s1.toString(), 16) + Integer.parseInt(s2.toString(), 16);
        return num;
    }

    /**
     * Checks whether checksum is valid or not in the given OSPF message.
     *
     * @param ospfMessage  ospf message instance
     * @param checksumPos1 position of checksum bit in packet
     * @param checksumPos2 position of checksum bit in packet
     * @return true if valid else false
     */
    public boolean isValidOspfCheckSum(OspfMessage ospfMessage, int checksumPos1, int checksumPos2) {

        switch (ospfMessage.ospfMessageType().value()) {
            case OspfParameters.HELLO:
                ospfMessage = (HelloPacket) ospfMessage;
                break;
            case OspfParameters.DD:
                ospfMessage = (DdPacket) ospfMessage;
                break;
            case OspfParameters.LSREQUEST:
                ospfMessage = (LsRequest) ospfMessage;
                break;
            case OspfParameters.LSUPDATE:
                ospfMessage = (LsUpdate) ospfMessage;
                break;
            case OspfParameters.LSACK:
                ospfMessage = (LsAcknowledge) ospfMessage;
                break;
            default:
                break;
        }

        byte[] messageAsBytes = ospfMessage.asBytes();
        return validateOspfCheckSum(messageAsBytes, checksumPos1, checksumPos2);
    }

    /**
     * Checks whether checksum is valid or not in the given OSPF LSA.
     *
     * @param ospfLsa         lsa instance
     * @param lsType          lsa type
     * @param lsaChecksumPos1 lsa checksum position in packet
     * @param lsaChecksumPos2 lsa checksum position in packet
     * @return true if valid else false
     * @throws Exception might throw exception while processing
     */
    public boolean isValidLsaCheckSum(OspfLsa ospfLsa, int lsType, int lsaChecksumPos1,
                                      int lsaChecksumPos2) throws Exception {
        if (lsType == OspfLsaType.ROUTER.value()) {
            RouterLsa lsa = (RouterLsa) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.NETWORK.value()) {
            NetworkLsa lsa = (NetworkLsa) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.SUMMARY.value()) {
            SummaryLsa lsa = (SummaryLsa) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.ASBR_SUMMARY.value()) {
            AsbrSummaryLsa lsa = (AsbrSummaryLsa) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.EXTERNAL_LSA.value()) {
            ExternalLsa lsa = (ExternalLsa) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value()) {
            OpaqueLsa9 lsa = (OpaqueLsa9) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.AREA_LOCAL_OPAQUE_LSA.value()) {
            OpaqueLsa10 lsa = (OpaqueLsa10) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        } else if (lsType == OspfLsaType.AS_OPAQUE_LSA.value()) {
            OpaqueLsa11 lsa = (OpaqueLsa11) ospfLsa;
            return validateLsaCheckSum(lsa.asBytes(), lsaChecksumPos1, lsaChecksumPos2);
        }

        return false;
    }

    /**
     * Verifies the checksum is valid in given LSA packet bytes.
     *
     * @param lsaPacket       lsa as byte array
     * @param lsaChecksumPos1 position of checksum bit in packet
     * @param lsaChecksumPos2 position of checksum bit in packet
     * @return true if valid else false
     */
    public boolean validateLsaCheckSum(byte[] lsaPacket, int lsaChecksumPos1, int lsaChecksumPos2) {

        byte[] checksum = calculateLsaChecksum(lsaPacket, lsaChecksumPos1, lsaChecksumPos2);

        if (lsaPacket[lsaChecksumPos1] == checksum[0] && lsaPacket[lsaChecksumPos2] == checksum[1]) {
            return true;
        }

        return false;
    }

    /**
     * Verifies the checksum is valid in given OSPF packet bytes.
     *
     * @param ospfPacket   as byte array
     * @param checksumPos1 position of checksum bit in packet
     * @param checksumPos2 position of checksum bit in packet
     * @return true if valid else false
     */
    public boolean validateOspfCheckSum(byte[] ospfPacket, int checksumPos1, int checksumPos2) {

        byte[] checkSum = calculateOspfCheckSum(ospfPacket, checksumPos1, checksumPos2);

        if (ospfPacket[checksumPos1] == checkSum[0] && ospfPacket[checksumPos2] == checkSum[1]) {
            return true;
        }

        return false;
    }

    /**
     * Calculates the LSA checksum.
     *
     * @param lsaBytes        as byte array
     * @param lsaChecksumPos1 position of checksum bit in packet
     * @param lsaChecksumPos2 position of checksum bit in packet
     * @return checksum bytes
     */
    public byte[] calculateLsaChecksum(byte[] lsaBytes, int lsaChecksumPos1, int lsaChecksumPos2) {

        byte[] tempLsaByte = Arrays.copyOf(lsaBytes, lsaBytes.length);

        int[] checksumOut = {0, 0};
        tempLsaByte[lsaChecksumPos1] = 0;
        tempLsaByte[lsaChecksumPos2] = 0;
        byte[] byteCheckSum = {0, 0};
        if (lsaBytes != null) {
            for (int i = 2; i < tempLsaByte.length; i++) {
                checksumOut[0] = checksumOut[0] + ((int) tempLsaByte[i] & 0xFF);
                checksumOut[1] = checksumOut[1] + checksumOut[0];
            }
            checksumOut[0] = checksumOut[0] % 255;
            checksumOut[1] = checksumOut[1] % 255;
        }
        int byte1 = (int) ((tempLsaByte.length - lsaChecksumPos1 - 1) * checksumOut[0] - checksumOut[1]) % 255;
        if (byte1 <= 0) {
            byte1 += 255;
        }
        int byte2 = 510 - checksumOut[0] - byte1;
        if (byte2 > 255) {
            byte2 -= 255;
        }

        byteCheckSum[0] = (byte) byte1;
        byteCheckSum[1] = (byte) byte2;

        return byteCheckSum;
    }

    /**
     * Calculate checksum from hexasum.
     *
     * @param hexasum total of 16 bits hexadecimal values
     * @return checksum value
     */
    private int calculateChecksum(int hexasum) {

        char[] tempZeros = {'0', '0', '0', '0'};
        StringBuffer hexaAsBinaryStr = new StringBuffer(Integer.toBinaryString(hexasum));
        int length = hexaAsBinaryStr.length();
        while (length > 16) {
            if (hexaAsBinaryStr.length() % 4 != 0) {
                int offset = hexaAsBinaryStr.length() % 4;
                hexaAsBinaryStr.insert(0, tempZeros, 0, 4 - offset);
            }
            StringBuffer hexaStr1 = new StringBuffer(hexaAsBinaryStr.reverse().substring(0, 16));
            String revHexaStr1 = hexaStr1.reverse().toString();
            StringBuffer hexaStr2 = new StringBuffer(hexaAsBinaryStr.reverse());
            StringBuffer hexaStr3 = new StringBuffer(hexaStr2.reverse().substring(16, hexaStr2.length()));
            String revHexaStr3 = hexaStr3.reverse().toString();
            int lastSixteenHexaBits = Integer.parseInt(revHexaStr1, 2);
            int remainingHexaBits = Integer.parseInt(revHexaStr3, 2);
            int totalCheckSum = lastSixteenHexaBits + remainingHexaBits;
            hexaAsBinaryStr = new StringBuffer(Integer.toBinaryString(totalCheckSum));
            length = hexaAsBinaryStr.length();
        }
        if (hexaAsBinaryStr.length() < 16) {
            int count = 16 - hexaAsBinaryStr.length();
            String s = hexaAsBinaryStr.toString();
            for (int i = 0; i < count; i++) {
                s = "0" + s;
            }

            hexaAsBinaryStr = new StringBuffer(s);

        }
        StringBuffer checksum = negate(hexaAsBinaryStr);
        return Integer.parseInt(checksum.toString(), 2);
    }

    /**
     * Negates given hexasum.
     *
     * @param binaryString binary form of hexasum
     * @return binary from of calculateChecksum
     */
    private StringBuffer negate(StringBuffer binaryString) {
        for (int i = 0; i < binaryString.length(); i++) {
            if (binaryString.charAt(i) == '1') {
                binaryString.replace(i, i + 1, "0");
            } else {
                binaryString.replace(i, i + 1, "1");
            }
        }

        return binaryString;
    }

    /**
     * Calculates the OSPF checksum for the given packet.
     *
     * @param packet       as byte array
     * @param checksumPos1 position of checksum bit in packet
     * @param checksumPos2 position of checksum bit in packet
     * @return checksum bytes
     */
    public byte[] calculateOspfCheckSum(byte[] packet, int checksumPos1, int checksumPos2) {

        int hexasum = 0;
        for (int i = 0; i < packet.length; i = i + 2) {
            if (i != 12) {
                byte b1 = packet[i];
                String s1 = String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replace(' ', '0');
                b1 = packet[i + 1];
                String s2 = String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replace(' ', '0');
                String hexa = s1 + s2;
                int num1 = Integer.parseInt(hexa, 2);
                hexasum = hexasum + num1;
                String convertTo16 = Integer.toHexString(hexasum);
                if (convertTo16.length() > 4) {
                    hexasum = convertToSixteenBits(convertTo16);
                }
            }
        }
        StringBuilder sb = new StringBuilder(Integer.toHexString(hexasum));
        if (sb.length() > 4) {
            sb = sb.reverse();
            StringBuilder s1 = new StringBuilder(sb.substring(0, 4));
            s1 = s1.reverse();
            StringBuilder s2 = new StringBuilder(sb.substring(4, sb.length()));
            s2 = s2.reverse();
            hexasum = Integer.parseInt(s1.toString(), 16) + Integer.parseInt(s2.toString(), 16);
        }
        int finalChecksum = calculateChecksum(hexasum);
        return OspfUtil.convertToTwoBytes(finalChecksum);
    }
}