/*
 * 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.lsa.types;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.primitives.Bytes;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.Ip4Address;
import org.onosproject.ospf.controller.OspfLsaType;
import org.onosproject.ospf.exceptions.OspfErrorType;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.lsa.LsaHeader;
import org.onosproject.ospf.protocol.lsa.subtypes.OspfExternalDestination;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * Representation of an External LSA and the fields and methods to access them.
 */
public class ExternalLsa extends LsaHeader {

    /*
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |            LS age             |     Options   |      5        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                        Link State ID                          |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                     Advertising Router                        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                     LS sequence number                        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |         LS checksum           |             length            |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                         Network Mask                          |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |E|     0       |                  metric                       |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                      Forwarding address                       |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                      External Route Tag                       |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |E|    TOS      |                TOS  metric                    |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                      Forwarding address                       |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                      External Route Tag                       |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                              ...                              |

        External LSA format
        REFERENCE : RFC 2328
     */
    private static final Logger log =
            LoggerFactory.getLogger(ExternalLsa.class);
    private Ip4Address networkMask;
    private List<OspfExternalDestination> externalDestinations = new ArrayList<>();

    /**
     * Creates an instance of External LSA.
     *
     * @param lsaHeader lsa header instance.
     */
    public ExternalLsa(LsaHeader lsaHeader) {
        populateHeader(lsaHeader);
    }


    /**
     * Gets the network mask.
     *
     * @return networkMask
     */
    public Ip4Address networkMask() {
        return networkMask;
    }

    /**
     * Sets network mask.
     *
     * @param networkMask network mask
     */
    public void setNetworkMask(Ip4Address networkMask) {
        this.networkMask = networkMask;
    }

    /**
     * Adds the external destination details to the list.
     *
     * @param externalDestination external destination details
     */
    public void addExternalDestination(OspfExternalDestination externalDestination) {
        if (!externalDestinations.contains(externalDestination)) {
            externalDestinations.add(externalDestination);
        }
    }

    /**
     * Reads from channel buffer and populate instance.
     *
     * @param channelBuffer channelBuffer instance
     * @throws OspfParseException might throws exception while parsing buffer
     */
    public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {

        try {
            byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
            channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
            this.setNetworkMask(Ip4Address.valueOf(tempByteArray));

            while (channelBuffer.readableBytes() >= OspfUtil.EXTERNAL_DESTINATION_LENGTH) {
                OspfExternalDestination externalDestination = new OspfExternalDestination();

                //E Bit - use to find type1 or type2
                int eIsSet = channelBuffer.readByte();
                if (eIsSet != 0) {
                    externalDestination.setType1orType2Metric(true);
                } else {
                    externalDestination.setType1orType2Metric(false);
                }
                externalDestination.setMetric(channelBuffer.readUnsignedMedium());
                tempByteArray = new byte[OspfUtil.FOUR_BYTES];
                channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
                externalDestination.setForwardingAddress(Ip4Address.valueOf(tempByteArray));
                externalDestination.setExternalRouterTag(channelBuffer.readInt());

                this.addExternalDestination(externalDestination);
            }
        } catch (Exception e) {
            log.debug("Error::ExternalLSA:: {}", e.getMessage());
            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR, OspfErrorType.BAD_MESSAGE);
        }
    }

    /**
     * Gets LSA as bytes.
     *
     * @return LSA as bytes.
     * @throws OspfParseException might throws exception while parsing packet
     */
    public byte[] asBytes() throws OspfParseException {
        byte[] lsaMessage = null;

        byte[] lsaHeader = getLsaHeaderAsByteArray();
        byte[] lsaBody = getLsaBodyAsByteArray();
        lsaMessage = Bytes.concat(lsaHeader, lsaBody);

        return lsaMessage;
    }

    /**
     * Gets LSA body as byte array.
     *
     * @return byte array contains LSA body
     * @throws OspfParseException might throws exception while parsing buffer
     */
    public byte[] getLsaBodyAsByteArray() throws OspfParseException {
        List<Byte> bodyLst = new ArrayList<>();

        try {
            bodyLst.addAll(Bytes.asList(this.networkMask().toOctets()));

            //add each OSPFExternalDestination details
            for (OspfExternalDestination externalDest : externalDestinations) {
                if (externalDest.isType1orType2Metric()) {
                    //add 1 followed by 7 zeros equals to decimal 128
                    bodyLst.add((byte) 128);
                } else {
                    bodyLst.add((byte) 0);
                }

                bodyLst.addAll(Bytes.asList(OspfUtil.convertToThreeBytes(externalDest.metric())));
                bodyLst.addAll(Bytes.asList(externalDest.forwardingAddress().toOctets()));
                bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(externalDest.externalRouterTag())));
            }
        } catch (Exception e) {
            log.debug("Error::getLsrBodyAsByteArray {}", e.getMessage());
            return Bytes.toArray(bodyLst);
        }

        return Bytes.toArray(bodyLst);
    }

    @Override
    public OspfLsaType getOspfLsaType() {
        return OspfLsaType.EXTERNAL_LSA;
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null || getClass() != other.getClass()) {
            return false;
        }
        ExternalLsa that = (ExternalLsa) other;
        return Objects.equal(networkMask, that.networkMask) &&
                Objects.equal(externalDestinations, that.externalDestinations);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(networkMask, externalDestinations);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("networkMask", networkMask)
                .add("externalDestinations", externalDestinations)
                .toString();
    }
}