/*
 * Copyright 2015 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.pcepio.protocol.ver1;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFecObjectIPv6;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides Pcep Fec Object IPv6 object.
 */
public class PcepFecObjectIPv6Ver1 implements PcepFecObjectIPv6 {

    /*
     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
     *
        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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       //                     IPv6 Node ID (16 bytes)                  //
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                       FEC Object-Type is 2 IPv6 Node ID
     */
    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6Ver1.class);

    public static final byte FEC_OBJ_TYPE = 2;
    public static final byte FEC_OBJ_CLASS = 63; //to be defined
    public static final byte FEC_OBJECT_VERSION = 1;
    public static final short FEC_OBJ_MINIMUM_LENGTH = 20;
    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
    public static final int IPV6_ADDRESS_LENGTH = 16;

    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);

    private PcepObjectHeader fecObjHeader;
    private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];

    /**
     * Constructor to initialize parameters for PCEP fec object.
     *
     * @param fecObjHeader Fec object header
     * @param nodeID node ID
     */
    public PcepFecObjectIPv6Ver1(PcepObjectHeader fecObjHeader, byte[] nodeID) {
        this.fecObjHeader = fecObjHeader;
        this.nodeID = nodeID;
    }

    /**
     * Sets the Object header.
     *
     * @param obj object header
     */
    public void setFecIpv6ObjHeader(PcepObjectHeader obj) {
        this.fecObjHeader = obj;
    }

    @Override
    public void setNodeID(byte[] nodeID) {
        this.nodeID = nodeID;
    }

    /**
     * Returns object header.
     *
     * @return fec Object Header
     */
    public PcepObjectHeader getFecIpv6ObjHeader() {
        return this.fecObjHeader;
    }

    @Override
    public byte[] getNodeID() {
        return this.nodeID;
    }

    /**
     * reads the channel buffer and returns object of PcepFecObjectIPv6.
     *
     * @param cb of channel buffer.
     * @return object of PcepFecObjectIPv6
     * @throws PcepParseException when fails to read from channel buffer
     */
    public static PcepFecObjectIPv6 read(ChannelBuffer cb) throws PcepParseException {

        PcepObjectHeader fecObjHeader;
        byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
        fecObjHeader = PcepObjectHeader.read(cb);
        cb.readBytes(nodeID, 0, IPV6_ADDRESS_LENGTH);
        return new PcepFecObjectIPv6Ver1(fecObjHeader, nodeID);
    }

    @Override
    public int write(ChannelBuffer cb) throws PcepParseException {

        int objStartIndex = cb.writerIndex();

        //write common header
        int objLenIndex = fecObjHeader.write(cb);
        cb.writeBytes(nodeID);

        //now write FEC IPv4 Object Length
        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
        return cb.writerIndex();
    }

    /**
     * Builder class for PCEP fec object IPv6.
     */
    public static class Builder implements PcepFecObjectIPv6.Builder {
        private boolean bIsHeaderSet = false;
        private boolean bIsNodeIdset = false;

        private PcepObjectHeader fecObjHeader;
        private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];

        private boolean bIsPFlagSet = false;
        private boolean bPFlag;

        private boolean bIsIFlagSet = false;
        private boolean bIFlag;

        @Override
        public PcepFecObjectIPv6 build() throws PcepParseException {
            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;

            if (!this.bIsNodeIdset) {
                throw new PcepParseException(" NodeID not set while building PcepFecObjectIPv6 object.");
            }
            if (bIsPFlagSet) {
                fecObjHeader.setPFlag(bPFlag);
            }
            if (bIsIFlagSet) {
                fecObjHeader.setIFlag(bIFlag);
            }
            return new PcepFecObjectIPv6Ver1(fecObjHeader, this.nodeID);
        }

        @Override
        public Builder setPFlag(boolean value) {
            this.bPFlag = value;
            this.bIsPFlagSet = true;
            return this;
        }

        @Override
        public Builder setIFlag(boolean value) {
            this.bIFlag = value;
            this.bIsIFlagSet = true;
            return this;
        }

        @Override
        public PcepObjectHeader getFecIpv6ObjHeader() {
            return this.fecObjHeader;
        }

        @Override
        public Builder setFecIpv6ObjHeader(PcepObjectHeader obj) {
            this.fecObjHeader = obj;
            this.bIsHeaderSet = true;
            return this;
        }

        @Override
        public byte[] getNodeID() {
            return this.nodeID;
        }

        @Override
        public Builder setNodeID(byte[] value) {
            this.nodeID = value;
            this.bIsNodeIdset = true;
            return this;
        }

    }

    @Override
    public PcepVersion getVersion() {
        return PcepVersion.PCEP_1;
    }

    @Override
    public int getType() {
        return FEC_OBJ_TYPE;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader).add("NodeID: ", nodeID)
                .toString();
    }
}
