/*
 * 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.isis.io.util;

import com.google.common.primitives.Bytes;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.isis.controller.IsisInterface;
import org.onosproject.isis.controller.IsisInterfaceState;
import org.onosproject.isis.controller.IsisNeighbor;
import org.onosproject.isis.controller.IsisPduType;
import org.onosproject.isis.controller.IsisRouterType;
import org.onosproject.isis.io.isispacket.IsisHeader;
import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
import org.onosproject.isis.io.isispacket.tlv.AdjacencyStateTlv;
import org.onosproject.isis.io.isispacket.tlv.AreaAddressTlv;
import org.onosproject.isis.io.isispacket.tlv.IpInterfaceAddressTlv;
import org.onosproject.isis.io.isispacket.tlv.IsisNeighborTlv;
import org.onosproject.isis.io.isispacket.tlv.PaddingTlv;
import org.onosproject.isis.io.isispacket.tlv.ProtocolSupportedTlv;
import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
import org.onosproject.isis.io.isispacket.tlv.TlvType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.DatatypeConverter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

/**
 * Representation of ISIS utils.
 */
public final class IsisUtil {
    public static final int ETHER_HEADER_LEN = 17;
    public static final int ID_SIX_BYTES = 6;
    public static final int ID_PLUS_ONE_BYTE = 7;
    public static final int ID_PLUS_TWO_BYTE = 8;
    public static final int THREE_BYTES = 3;
    public static final int TWO_BYTES = 2;
    public static final int SIX_BYTES = 6;
    public static final int EIGHT_BYTES = 8;
    public static final int FOUR_BYTES = 4;
    public static final int PADDING_FIXED_LENGTH = 255;
    public static final int TLVHEADERLENGTH = 2;
    public static final int INITIAL_BANDWIDTH = 12500000;
    private static final Logger log = LoggerFactory.getLogger(IsisUtil.class);

    /**
     * Creates an instance.
     */
    private IsisUtil() {

    }

    /**
     * Checks given IPs are in same network or not.
     *
     * @param ip1  IP address
     * @param ip2  IP address
     * @param mask network mask
     * @return true if both are in same network else false
     */
    public static boolean sameNetwork(Ip4Address ip1, Ip4Address ip2, byte[] mask) {
        try {
            byte[] a1 = ip1.toOctets();
            byte[] a2 = ip2.toOctets();
            for (int i = 0; i < a1.length; i++) {
                if ((a1[i] & mask[i]) != (a2[i] & mask[i])) {
                    return false;
                }
            }
        } catch (Exception e) {
            log.debug("Exception::IsisUtil::sameNetwork:: {}", e.getMessage());
        }
        return true;
    }

    /**
     * Parse byte array to string system ID.
     *
     * @param bytes system ID
     * @return systemId system ID
     */
    public static String systemId(byte[] bytes) {
        String systemId = "";
        for (Byte byt : bytes) {
            String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
            if (hexa.length() % 2 != 0) {
                hexa = "0" + hexa;
            }
            systemId = systemId + hexa;
            if (systemId.length() == 4 || systemId.length() == 9) {
                systemId = systemId + ".";
            }
        }
        return systemId;
    }

    /**
     * Parse byte array to LAN ID.
     *
     * @param bytes LAN ID
     * @return systemIdPlus system ID
     */
    public static String systemIdPlus(byte[] bytes) {
        int count = 1;
        String systemId = "";
        for (Byte byt : bytes) {
            String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
            if (hexa.length() % 2 != 0) {
                hexa = "0" + hexa;
            }
            if (count == 7 && bytes.length == 8) {
                systemId = systemId + hexa + "-";
            } else {
                systemId = systemId + hexa;
            }
            if (systemId.length() == 4 || systemId.length() == 9
                    || systemId.length() == 14) {
                systemId = systemId + ".";
            }
            count++;
        }
        return systemId;
    }

    /**
     * Parse byte array to area address.
     *
     * @param bytes area address
     * @return areaAddress area address
     */
    public static String areaAddress(byte[] bytes) {
        String areaAddres = "";
        for (Byte byt : bytes) {
            String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
            if (hexa.length() % 2 != 0) {
                hexa = "0" + hexa;
            }
            areaAddres = areaAddres + hexa;
        }
        return areaAddres;
    }

    /**
     * Parse area address to bytes.
     *
     * @param address area address
     * @return areaAddress area address
     */
    public static List<Byte> areaAddressToBytes(String address) {
        List<Byte> idList = new ArrayList<>();
        for (int i = 0; i < address.length(); i = i + 2) {
            Character c1 = address.charAt(i);
            Character c2 = address.charAt(i + 1);
            String str = c1.toString() + c2.toString();
            idList.add((byte) Integer.parseInt(str, 16));
        }
        return idList;
    }

    /**
     * Returns PDU headaer length.
     *
     * @param pduType PDU type
     * @return headerLength header length
     */
    public static int getPduHeaderLength(int pduType) {
        int headerLength = 0;
        switch (IsisPduType.get(pduType)) {
            case L1HELLOPDU:
            case L2HELLOPDU:
            case L1LSPDU:
            case L2LSPDU:
                headerLength = IsisConstants.HELLOHEADERLENGTH;
                break;
            case P2PHELLOPDU:
                headerLength = IsisConstants.P2PHELLOHEADERLENGTH;
                break;
            case L1PSNP:
            case L2PSNP:
                headerLength = IsisConstants.PSNPDUHEADERLENGTH;
                break;
            case L1CSNP:
            case L2CSNP:
                headerLength = IsisConstants.CSNPDUHEADERLENGTH;
                break;
            default:
                break;
        }
        return headerLength;
    }

    /**
     * Adds the PDU length in packet.
     *
     * @param isisPacket      ISIS packet
     * @param lengthBytePos1  length byte position
     * @param lengthBytePos2  length byte position
     * @param reservedBytePos reserved byte position
     * @return byte array with PDU length
     */
    public static byte[] addLengthAndMarkItInReserved(byte[] isisPacket, int lengthBytePos1,
                                                      int lengthBytePos2, int reservedBytePos) {
        //Set the length of the packet
        //Get the total length of the packet
        int length = isisPacket.length;
        //Convert the lenth to two bytes as the length field is 2 bytes
        byte[] lenthInTwoBytes = IsisUtil.convertToTwoBytes(length);
        //isis header 3rd and 4th position represents length
        isisPacket[lengthBytePos1] = lenthInTwoBytes[0]; //assign 1st byte in lengthBytePos1
        isisPacket[lengthBytePos2] = lenthInTwoBytes[1]; //assign 2st byte in lengthBytePos2
        isisPacket[reservedBytePos] = (byte) lengthBytePos1;
        return isisPacket;
    }

    /**
     * Adds the checksum in packet.
     *
     * @param isisPacket       ISIS packet
     * @param checksumBytePos1 checksum byte position
     * @param checksumBytePos2 checksum byte position
     * @return byte array with PDU length
     */
    public static byte[] addChecksum(byte[] isisPacket, int checksumBytePos1, int checksumBytePos2) {
        //Set the checksum for the packet
        //Convert the length to two bytes as the length field is 2 bytes
        byte[] checksumInTwoBytes = new ChecksumCalculator().calculateLspChecksum(
                isisPacket, checksumBytePos1, checksumBytePos2);
        //isis header 3rd and 4th position represents length
        isisPacket[checksumBytePos1] = checksumInTwoBytes[0];
        isisPacket[checksumBytePos2] = checksumInTwoBytes[1];
        return isisPacket;
    }

    /**
     * Adds frame a packet of 1498 of size.
     *
     * @param isisPacket     ISIS packet
     * @param interfaceIndex interface index
     * @return byte array with 1498 is the length
     */
    public static byte[] framePacket(byte[] isisPacket, int interfaceIndex) {
        //Set the length of the packet
        //Get the total length of the packet
        int length = isisPacket.length;
        //PDU_LENGTH + 1 byte for interface index
        if (length < IsisConstants.PDU_LENGTH + 1) {
            byte[] bytes = new byte[IsisConstants.PDU_LENGTH + 1];
            System.arraycopy(isisPacket, 0, bytes, 0, length);
            bytes[IsisConstants.PDU_LENGTH] = (byte) interfaceIndex;
            return bytes;
        }
        return isisPacket;
    }

    /**
     * Parse source and LAN ID.
     *
     * @param id source and LAN ID
     * @return source and LAN ID
     */
    public static List<Byte> sourceAndLanIdToBytes(String id) {
        List<Byte> idList = new ArrayList<>();
        StringTokenizer tokenizer = new StringTokenizer(id, "." + "-");
        while (tokenizer.hasMoreElements()) {
            int i = 0;
            String str = tokenizer.nextToken();
            idList.add((byte) Integer.parseInt(str.substring(0, i + 2), 16));
            if (str.length() > 2) {
                idList.add((byte) Integer.parseInt(str.substring(i + 2, str.length()), 16));
            }
        }
        return idList;
    }

    /**
     * Parse padding for PDU based on current length.
     *
     * @param currentLength current length
     * @return byteArray padding array
     */
    public static byte[] getPaddingTlvs(int currentLength) {
        List<Byte> bytes = new ArrayList<>();
        while (IsisConstants.PDU_LENGTH > currentLength) {
            int length = IsisConstants.PDU_LENGTH - currentLength;
            TlvHeader tlvHeader = new TlvHeader();
            tlvHeader.setTlvType(TlvType.PADDING.value());
            if (length >= PADDING_FIXED_LENGTH) {
                tlvHeader.setTlvLength(PADDING_FIXED_LENGTH);
            } else {
                tlvHeader.setTlvLength(IsisConstants.PDU_LENGTH - (currentLength + TLVHEADERLENGTH));
            }
            PaddingTlv tlv = new PaddingTlv(tlvHeader);
            bytes.addAll(Bytes.asList(tlv.asBytes()));
            currentLength = currentLength + tlv.tlvLength() + TLVHEADERLENGTH;
        }
        byte[] byteArray = new byte[bytes.size()];
        int i = 0;
        for (byte byt : bytes) {
            byteArray[i++] = byt;
        }
        return byteArray;
    }

    /**
     * Converts an integer to two bytes.
     *
     * @param numberToConvert number to convert
     * @return numInBytes given number as bytes
     */
    public static byte[] convertToTwoBytes(int numberToConvert) {

        byte[] numInBytes = new byte[2];
        String s1 = Integer.toHexString(numberToConvert);
        if (s1.length() % 2 != 0) {
            s1 = "0" + s1;
        }
        byte[] hexas = DatatypeConverter.parseHexBinary(s1);
        if (hexas.length == 1) {
            numInBytes[0] = 0;
            numInBytes[1] = hexas[0];
        } else {
            numInBytes[0] = hexas[0];
            numInBytes[1] = hexas[1];
        }
        return numInBytes;
    }

    /**
     * Converts a number to four bytes.
     *
     * @param numberToConvert number to convert
     * @return numInBytes given number as bytes
     */
    public static byte[] convertToFourBytes(int numberToConvert) {
        byte[] numInBytes = new byte[4];
        String s1 = Integer.toHexString(numberToConvert);
        if (s1.length() % 2 != 0) {
            s1 = "0" + s1;
        }
        byte[] hexas = DatatypeConverter.parseHexBinary(s1);
        if (hexas.length == 1) {
            numInBytes[0] = 0;
            numInBytes[1] = 0;
            numInBytes[2] = 0;
            numInBytes[3] = hexas[0];
        } else if (hexas.length == 2) {
            numInBytes[0] = 0;
            numInBytes[1] = 0;
            numInBytes[2] = hexas[0];
            numInBytes[3] = hexas[1];
        } else if (hexas.length == 3) {
            numInBytes[0] = 0;
            numInBytes[1] = hexas[0];
            numInBytes[2] = hexas[1];
            numInBytes[3] = hexas[2];
        } else {
            numInBytes[0] = hexas[0];
            numInBytes[1] = hexas[1];
            numInBytes[2] = hexas[2];
            numInBytes[3] = hexas[3];
        }
        return numInBytes;
    }

    /**
     * Returns the P2P hello PDU.
     *
     * @param isisInterface  ISIS interface instance
     * @param paddingEnabled padding enabled or not
     * @return hello PDU
     */
    public static byte[] getP2pHelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
        IsisHeader isisHeader = new IsisHeader();
        isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
        isisHeader.setPduHeaderLength((byte) IsisConstants.P2PHELLOHEADERLENGTH);
        isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
        isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
        isisHeader.setIsisPduType(IsisPduType.P2PHELLOPDU.value());
        isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
        isisHeader.setReserved((byte) IsisConstants.PDULENGTHPOSITION);
        isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
        P2PHelloPdu p2pHelloPdu = new P2PHelloPdu(isisHeader);
        p2pHelloPdu.setCircuitType((byte) isisInterface.reservedPacketCircuitType());
        p2pHelloPdu.setSourceId(isisInterface.systemId());
        p2pHelloPdu.setHoldingTime(isisInterface.holdingTime());
        p2pHelloPdu.setPduLength(IsisConstants.PDU_LENGTH);
        p2pHelloPdu.setLocalCircuitId((byte) IsisConstants.LOCALCIRCUITIDFORP2P);

        TlvHeader tlvHeader = new TlvHeader();
        tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
        tlvHeader.setTlvLength(0);
        AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
        areaAddressTlv.addAddress(isisInterface.areaAddress());
        p2pHelloPdu.addTlv(areaAddressTlv);

        tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
        tlvHeader.setTlvLength(0);
        ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
        protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
        p2pHelloPdu.addTlv(protocolSupportedTlv);

        tlvHeader.setTlvType(TlvType.ADJACENCYSTATE.value());
        tlvHeader.setTlvLength(0);
        AdjacencyStateTlv adjacencyStateTlv = new AdjacencyStateTlv(tlvHeader);
        adjacencyStateTlv.setAdjacencyType((byte) IsisInterfaceState.DOWN.value());
        adjacencyStateTlv.setLocalCircuitId(Integer.parseInt(isisInterface.circuitId()));
        Set<MacAddress> neighbors = isisInterface.neighbors();
        if (!neighbors.isEmpty()) {
            IsisNeighbor neighbor = isisInterface.lookup(neighbors.iterator().next());
            adjacencyStateTlv.setAdjacencyType((byte) neighbor.interfaceState().value());
            adjacencyStateTlv.setNeighborSystemId(neighbor.neighborSystemId());
            adjacencyStateTlv.setNeighborLocalCircuitId(neighbor.localExtendedCircuitId());
        }
        p2pHelloPdu.addTlv(adjacencyStateTlv);

        tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
        tlvHeader.setTlvLength(0);
        IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
        ipInterfaceAddressTlv.addInterfaceAddres(isisInterface.interfaceIpAddress());
        p2pHelloPdu.addTlv(ipInterfaceAddressTlv);

        byte[] beforePadding = p2pHelloPdu.asBytes();
        byte[] helloMessage;
        if (paddingEnabled) {
            byte[] paddingTlvs = getPaddingTlvs(beforePadding.length);
            helloMessage = Bytes.concat(beforePadding, paddingTlvs);
        } else {
            helloMessage = beforePadding;
        }
        return helloMessage;
    }

    /**
     * Returns the L1 hello PDU.
     *
     * @param isisInterface  ISIS interface instance
     * @param paddingEnabled padding enabled or not
     * @return helloMessage hello PDU
     */
    public static byte[] getL1HelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
        return getL1OrL2HelloPdu(isisInterface, IsisPduType.L1HELLOPDU, paddingEnabled);
    }

    /**
     * Returns the L2 hello PDU.
     *
     * @param isisInterface  ISIS interface instance
     * @param paddingEnabled padding enabled or not
     * @return helloMessage hello PDU
     */
    public static byte[] getL2HelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
        return getL1OrL2HelloPdu(isisInterface, IsisPduType.L2HELLOPDU, paddingEnabled);
    }

    /**
     * Returns the hello PDU.
     *
     * @param isisInterface  ISIS interface instance
     * @param paddingEnabled padding enabled or not
     * @return helloMessage hello PDU
     */
    private static byte[] getL1OrL2HelloPdu(IsisInterface isisInterface, IsisPduType isisPduType,
                                            boolean paddingEnabled) {
        String lanId = "";
        IsisHeader isisHeader = new IsisHeader();
        isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
        isisHeader.setPduHeaderLength((byte) IsisConstants.HELLOHEADERLENGTH);
        isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
        isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
        if (isisPduType == IsisPduType.L1HELLOPDU) {
            isisHeader.setIsisPduType(IsisPduType.L1HELLOPDU.value());
            lanId = isisInterface.l1LanId();
        } else if (isisPduType == IsisPduType.L2HELLOPDU) {
            isisHeader.setIsisPduType(IsisPduType.L2HELLOPDU.value());
            lanId = isisInterface.l2LanId();
        }
        isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
        isisHeader.setReserved((byte) IsisConstants.PDULENGTHPOSITION);
        isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
        L1L2HelloPdu l1L2HelloPdu = new L1L2HelloPdu(isisHeader);
        l1L2HelloPdu.setCircuitType((byte) isisInterface.reservedPacketCircuitType());
        l1L2HelloPdu.setSourceId(isisInterface.systemId());
        l1L2HelloPdu.setHoldingTime(isisInterface.holdingTime());
        l1L2HelloPdu.setPduLength(IsisConstants.PDU_LENGTH);
        l1L2HelloPdu.setPriority((byte) isisInterface.priority());
        l1L2HelloPdu.setLanId(lanId);
        TlvHeader tlvHeader = new TlvHeader();
        tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
        tlvHeader.setTlvLength(0);
        AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
        areaAddressTlv.addAddress(isisInterface.areaAddress());
        l1L2HelloPdu.addTlv(areaAddressTlv);
        Set<MacAddress> neighbors = isisInterface.neighbors();
        if (!neighbors.isEmpty()) {
            List<MacAddress> neighborMacs = new ArrayList<>();
            for (MacAddress neighbor : neighbors) {
                IsisNeighbor isisNeighbor = isisInterface.lookup(neighbor);
                if (isisPduType == IsisPduType.L1HELLOPDU) {
                    if (isisNeighbor.routerType() == IsisRouterType.L1 ||
                            isisNeighbor.routerType() == IsisRouterType.L1L2) {
                        neighborMacs.add(neighbor);
                    }
                } else if (isisPduType == IsisPduType.L2HELLOPDU) {
                    if (isisNeighbor.routerType() == IsisRouterType.L2 ||
                            isisNeighbor.routerType() == IsisRouterType.L1L2) {
                        neighborMacs.add(neighbor);
                    }
                }
            }

            tlvHeader.setTlvType(TlvType.ISNEIGHBORS.value());
            tlvHeader.setTlvLength(0);

            IsisNeighborTlv isisNeighborTlv = new IsisNeighborTlv(tlvHeader);
            for (MacAddress neighbor : neighborMacs) {
                isisNeighborTlv.addNeighbor(neighbor);
            }
            l1L2HelloPdu.addTlv(isisNeighborTlv);
        }

        tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
        tlvHeader.setTlvLength(0);
        ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
        protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
        l1L2HelloPdu.addTlv(protocolSupportedTlv);

        tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
        tlvHeader.setTlvLength(0);
        IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
        ipInterfaceAddressTlv.addInterfaceAddres(isisInterface.interfaceIpAddress());
        l1L2HelloPdu.addTlv(ipInterfaceAddressTlv);

        byte[] beforePadding = l1L2HelloPdu.asBytes();
        byte[] helloMessage;
        if (paddingEnabled) {
            byte[] paddingTlvs = getPaddingTlvs(beforePadding.length);
            helloMessage = Bytes.concat(beforePadding, paddingTlvs);
        } else {
            helloMessage = beforePadding;
        }
        return helloMessage;
    }

    /**
     * Converts a byte to integer variable.
     *
     * @param bytesToConvert bytes to convert
     * @return integer representation of bytes
     */
    public static int byteToInteger(byte[] bytesToConvert) {
        final StringBuilder builder = new StringBuilder();
        for (byte eachByte : bytesToConvert) {
            builder.append(String.format("%02x", eachByte));
        }
        int number = Integer.parseInt(builder.toString(), 16);
        return number;
    }

    /**
     * Converts a byte to long variable.
     *
     * @param bytesToConvert bytes to convert
     * @return long representation of bytes
     */
    public static long byteToLong(byte[] bytesToConvert) {
        final StringBuilder builder = new StringBuilder();
        for (byte eachByte : bytesToConvert) {
            builder.append(String.format("%02x", eachByte));
        }
        long number = Long.parseLong(builder.toString(), 16);
        return number;
    }

    /**
     * Converts a number to four bytes.
     *
     * @param numberToConvert number to convert
     * @return numInBytes given number as bytes
     */
    public static byte[] convertToFourBytes(long numberToConvert) {
        byte[] numInBytes = new byte[4];
        String s1 = Long.toHexString(numberToConvert);
        if (s1.length() % 2 != 0) {
            s1 = "0" + s1;
        }
        if (s1.length() == 16) {
            s1 = s1.substring(8, s1.length());
        }
        byte[] hexas = DatatypeConverter.parseHexBinary(s1);
        if (hexas.length == 1) {
            numInBytes[0] = 0;
            numInBytes[1] = 0;
            numInBytes[2] = 0;
            numInBytes[3] = hexas[0];
        } else if (hexas.length == 2) {
            numInBytes[0] = 0;
            numInBytes[1] = 0;
            numInBytes[2] = hexas[0];
            numInBytes[3] = hexas[1];
        } else if (hexas.length == 3) {
            numInBytes[0] = 0;
            numInBytes[1] = hexas[0];
            numInBytes[2] = hexas[1];
            numInBytes[3] = hexas[2];
        } else {
            numInBytes[0] = hexas[0];
            numInBytes[1] = hexas[1];
            numInBytes[2] = hexas[2];
            numInBytes[3] = hexas[3];
        }
        return numInBytes;
    }

    /**
     * Converts a number to eight bit binary.
     *
     * @param binaryString string to binary
     * @return numInBytes given number as bytes
     */
    public static String toEightBitBinary(String binaryString) {
        String eightBit = binaryString;
        if (eightBit.length() % 8 != 0) {
            int numOfZero = 8 - eightBit.length();
            while (numOfZero > 0) {
                eightBit = "0" + eightBit;
                numOfZero--;
            }
        }
        return eightBit;
    }

    /**
     * Converts a number to four bit binary.
     *
     * @param binaryString string to binary
     * @return numInBytes given number as bytes
     */
    public static String toFourBitBinary(String binaryString) {
        String fourBit = binaryString;
        if (fourBit.length() % 4 != 0) {
            int numOfZero = 4 - fourBit.length();
            while (numOfZero > 0) {
                fourBit = "0" + fourBit;
                numOfZero--;
            }
        }
        return fourBit;
    }

    /**
     * Converts a number to three bytes.
     *
     * @param numberToConvert number to convert
     * @return given number as bytes
     */
    public static byte[] convertToThreeBytes(int numberToConvert) {
        byte[] numInBytes = new byte[3];
        String s1 = Integer.toHexString(numberToConvert);
        if (s1.length() % 2 != 0) {
            s1 = "0" + s1;
        }
        byte[] hexas = DatatypeConverter.parseHexBinary(s1);
        if (hexas.length == 1) {
            numInBytes[0] = 0;
            numInBytes[1] = 0;
            numInBytes[2] = hexas[0];
        } else if (hexas.length == 2) {
            numInBytes[0] = 0;
            numInBytes[1] = hexas[0];
            numInBytes[2] = hexas[1];
        } else {
            numInBytes[0] = hexas[0];
            numInBytes[1] = hexas[1];
            numInBytes[2] = hexas[2];
        }
        return numInBytes;
    }

    /**
     * Converts the bytes of prefix to string type value.
     *
     * @param bytes array of prefix
     * @return string value of prefix
     */
    public static String prefixConversion(byte[] bytes) {
        String prefix = "";
        for (int i = 0; i < bytes.length; i++) {
            if (i < (bytes.length - 1)) {
                prefix = prefix + bytes[i] + ".";
            } else {
                prefix = prefix + bytes[i];
            }
        }
        return prefix;
    }

    /**
     * Converts the prefix to bytes.
     *
     * @param prefix prefix
     * @return prefix to bytes
     */
    public static byte[] prefixToBytes(String prefix) {
        List<Byte> byteList = new ArrayList<>();
        StringTokenizer tokenizer = new StringTokenizer(prefix, ".");
        while (tokenizer.hasMoreTokens()) {
            byteList.add((byte) Integer.parseInt(tokenizer.nextToken()));
        }
        return Bytes.toArray(byteList);
    }

    /**
     * Return the DIS value from the systemId.
     *
     * @param systemId system Id.
     * @return return true if DIS else false
     */
    public static boolean checkIsDis(String systemId) {
        StringTokenizer stringTokenizer = new StringTokenizer(systemId, "." + "-");
        int count = 0;
        while (stringTokenizer.hasMoreTokens()) {
            String str = stringTokenizer.nextToken();
            if (count == 3) {
                int x = Integer.parseInt(str);
                if (x > 0) {
                    return true;
                }
            }
            count++;
        }
        return false;
    }

    /**
     * Return the systemId.
     *
     * @param systemId system Id.
     * @return return system ID
     */
    public static String removeTailingZeros(String systemId) {
        StringTokenizer stringTokenizer = new StringTokenizer(systemId, "-");
        return stringTokenizer.nextToken();
    }
}
