/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.exceptions.OspfParseException;
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.controller.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 org.slf4j.Logger;

import java.util.Arrays;

import static org.slf4j.LoggerFactory.getLogger;

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

    private static final Logger log = getLogger(ChecksumCalculator.class);

    /**
     * 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
     * @throws OspfParseException if packet can't be parsed
     * @return true if valid else false
     */
    public boolean isValidLsaCheckSum(OspfLsa ospfLsa, int lsType, int lsaChecksumPos1,
                                      int lsaChecksumPos2) throws OspfParseException {

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