/*
 * 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.onlab.packet.Ip4Address;
import org.onosproject.ospf.exceptions.OspfErrorType;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.lsa.LsaHeader;
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 a Network LSA and fields and methods to access them.
 */
public class NetworkLsa 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  |      2        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                        Link State ID                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     Advertising Router                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     LS sequence number                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |         LS checksum           |             length            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         Network Mask                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                        Attached Router                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                              ...                              |
     */
    private static final Logger log =
            LoggerFactory.getLogger(NetworkLsa.class);
    private Ip4Address networkMask;
    private List<Ip4Address> attachedRouters = new ArrayList<>();

    /**
     * Creates an instance of Network LSA.
     */
    public NetworkLsa() {
    }

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

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

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

    /**
     * Adds attached router to list.
     *
     * @param attachedRouter attached router ip address.
     */
    public void addAttachedRouter(Ip4Address attachedRouter) {
        attachedRouters.add(attachedRouter);
    }

    /**
     * Reads from channel buffer and populate instance.
     *
     * @param channelBuffer channel buffer 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));
            //add all the attached routers
            while (channelBuffer.readableBytes() > 0) {
                tempByteArray = new byte[OspfUtil.FOUR_BYTES];
                channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
                this.addAttachedRouter(Ip4Address.valueOf(tempByteArray));
            }
        } catch (Exception e) {
            log.debug("Error::NetworkLSA::readFrom:: {}", e.getMessage());
            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR, OspfErrorType.BAD_MESSAGE);
        }
    }

    /**
     * Gets LSA as bytes.
     *
     * @return LSA as byte array
     * @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 LSA body as byte array
     * @throws OspfParseException might throws exception while parsing packet
     */
    public byte[] getLSABodyAsByteArray() throws OspfParseException {
        List<Byte> bodyLst = new ArrayList<>();

        try {
            bodyLst.addAll(Bytes.asList(this.networkMask().toOctets()));
            //add each attachedRouters details
            for (Ip4Address attachedRouter : attachedRouters) {
                //attached router
                bodyLst.addAll(Bytes.asList(attachedRouter.toOctets()));
            }
        } catch (Exception e) {
            log.debug("Error::NetworkLSA::getLsrBodyAsByteArray {}", e.getMessage());
            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR, OspfErrorType.BAD_MESSAGE);
        }

        return Bytes.toArray(bodyLst);
    }

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

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

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