/*
 * Copyright 2016 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.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.onosproject.ospf.controller.OspfLsaType;
import org.onosproject.ospf.exceptions.OspfErrorType;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
import org.onosproject.ospf.protocol.lsa.TlvHeader;
import org.onosproject.ospf.protocol.lsa.tlvtypes.LinkTlv;
import org.onosproject.ospf.protocol.lsa.tlvtypes.OpaqueTopLevelTlvTypes;
import org.onosproject.ospf.protocol.lsa.tlvtypes.RouterTlv;
import org.onosproject.ospf.protocol.util.OspfParameters;

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

/**
 * Representation of an Opaque LSA of type area local (10).
 */
public class OpaqueLsa10 extends OpaqueLsaHeader {
    /*
      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   |   9, 10 or 11 |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Opaque Type  |               Opaque ID                       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      Advertising Router                       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      LS Sequence Number                       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |         LS checksum           |           Length              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               |
     +                                                               +
     |                      Opaque Information                       |
     +                                                               +
     |                              ...                              |

        Opaque LSA format
        REFERENCE : RFC 5250
    */
    private List<TopLevelTlv> topLevelValues = new ArrayList<>();
    private byte[] opaqueInfo = null;

    /**
     * Creates an instance of Opaque type 10 LSA.
     *
     * @param lsaHeader LSA header instance
     */
    public OpaqueLsa10(OpaqueLsaHeader lsaHeader) {
        populateHeader(lsaHeader);
    }

    /**
     * Returns the list of top level TLVs.
     *
     * @return list of top level TLVs
     */
    public List<TopLevelTlv> topLevelValues() {
        return topLevelValues;
    }

    /**
     * Adds TLV value.
     *
     * @param value TLV value
     */
    public void addValue(TopLevelTlv value) {
        topLevelValues.add(value);
    }

    /**
     * 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 {
            if (this.opaqueId() == OspfParameters.TRAFFIC_ENGINEERING) {
                while (channelBuffer.readableBytes() > 0) {
                    TlvHeader tlvHeader = new TlvHeader();
                    tlvHeader.setTlvType(channelBuffer.readUnsignedShort());
                    tlvHeader.setTlvLength(channelBuffer.readUnsignedShort());
                    if (tlvHeader.tlvType() == OpaqueTopLevelTlvTypes.ROUTER.value()) {
                        RouterTlv routerTlv = new RouterTlv(tlvHeader);
                        routerTlv.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
                        this.addValue(routerTlv);
                    } else if (tlvHeader.tlvType() == OpaqueTopLevelTlvTypes.LINK.value()) {
                        LinkTlv linkTlv = new LinkTlv(tlvHeader);
                        linkTlv.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
                        this.addValue(linkTlv);
                    }
                }
            } else {
                int length = channelBuffer.readableBytes();
                opaqueInfo = new byte[length];
                channelBuffer.readBytes(opaqueInfo, 0, length);
            }

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

    /**
     * Returns instance as bytes.
     *
     * @return instance as bytes
     * @throws Exception might throws exception while parsing packet
     */
    public byte[] asBytes() throws Exception {

        byte[] lsaMessage = null;
        byte[] lsaHeader = getOpaqueLsaHeaderAsByteArray();
        byte[] lsaBody = getLsaBodyAsByteArray();
        lsaMessage = Bytes.concat(lsaHeader, lsaBody);
        return lsaMessage;

    }

    /**
     * Gets the LSA body as byte array.
     *
     * @return the lsa body as byte array
     * @throws Exception might throws exception while parsing packet
     */
    public byte[] getLsaBodyAsByteArray() throws Exception {
        List<Byte> bodyLst = new ArrayList<>();
        if (this.opaqueId() == 1) {
            for (TopLevelTlv tlv : this.topLevelValues) {
                //Check the sub type of lsa and build bytes accordingly
                if (tlv instanceof RouterTlv) {
                    RouterTlv routerTlv = (RouterTlv) tlv;
                    bodyLst.addAll(Bytes.asList(routerTlv.asBytes()));
                } else if (tlv instanceof LinkTlv) {
                    LinkTlv linkTlv = (LinkTlv) tlv;
                    bodyLst.addAll(Bytes.asList(linkTlv.asBytes()));
                }
            }
        } else {
            return opaqueInfo;
        }

        return Bytes.toArray(bodyLst);
    }

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

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

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        OpaqueLsa10 that = (OpaqueLsa10) o;
        return Objects.equal(topLevelValues, that.topLevelValues) &&
                Objects.equal(opaqueInfo, that.opaqueInfo);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(opaqueInfo, topLevelValues);
    }
}