/*
 * 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 java.util.LinkedList;
import java.util.ListIterator;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFecObject;
import org.onosproject.pcepio.protocol.PcepLabelObject;
import org.onosproject.pcepio.protocol.PcepLabelUpdate;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepSrpObject;
import org.onosproject.pcepio.types.PcepLabelDownload;
import org.onosproject.pcepio.types.PcepLabelMap;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP LABEL update .
 * Reference :draft-zhao-pce-pcep-extension-for-pce-controller-01.
 */
public class PcepLabelUpdateVer1 implements PcepLabelUpdate {

    /*
     *       <pce-label-update>      ::= (<pce-label-download>|<pce-label-map>)

            Where:
             <pce-label-download>    ::= <SRP>
                                         <LSP>
                                         <label-list>

             <pce-label-map>         ::= <SRP>
                                         <LABEL>
                                         <FEC>

             <label-list >           ::= <LABEL>
                                         [<label-list>]
     */
    protected static final Logger log = LoggerFactory.getLogger(PcepLabelUpdateVer1.class);

    //Either PceLabelDownload or PceLabelMap is mandatory.
    //label Download
    private PcepLabelDownload labelDownload;
    private boolean isLabelDownloadSet;
    //label Map
    private PcepLabelMap labelMap;
    private boolean isLabelMapSet;

    /**
     * Constructor to reset parameters.
     */
    public PcepLabelUpdateVer1() {
        this.labelDownload = null;
        this.isLabelDownloadSet = false;
        this.labelMap = null;
        this.isLabelMapSet = false;
    }

    /**
     * Constructor to initialize PCEP label download.
     *
     * @param labelDownload PCEP label download
     */
    public PcepLabelUpdateVer1(PcepLabelDownload labelDownload) {
        this.labelDownload = labelDownload;
        this.isLabelDownloadSet = true;
        this.labelMap = null;
        this.isLabelMapSet = false;
    }

    /**
     * Constructor to initialize PCEP label map.
     *
     * @param labelMap PCEP label map
     */
    public PcepLabelUpdateVer1(PcepLabelMap labelMap) {
        this.labelDownload = null;
        this.isLabelDownloadSet = false;
        this.labelMap = labelMap;
        this.isLabelMapSet = true;
    }

    /**
     * builder class for PCEP label update.
     */
    static class Builder implements PcepLabelUpdate.Builder {

        private PcepLabelDownload labelDownload;
        private boolean isLabelDownloadSet;
        private PcepLabelMap labelMap;
        private boolean isLabelMapSet;

        @Override
        public PcepLabelUpdate build() throws PcepParseException {

            if (isLabelDownloadSet) {
                return new PcepLabelUpdateVer1(labelDownload);
            }
            if (isLabelMapSet) {
                return new PcepLabelUpdateVer1(labelMap);
            }
            if (!isLabelDownloadSet && !isLabelMapSet) {
                throw new PcepParseException(
                        "Label Download or Label Map is not set while building PcepLabelUpdate Message");
            }
            return new PcepLabelUpdateVer1();
        }

        @Override
        public Builder setLabelDownload(PcepLabelDownload labelDownload) {
            this.labelDownload = labelDownload;
            this.isLabelDownloadSet = true;
            return this;
        }

        @Override
        public PcepLabelDownload getLabelDownload() {
            return labelDownload;
        }

        @Override
        public Builder setLabelMap(PcepLabelMap labelMap) {
            this.labelMap = labelMap;
            this.isLabelMapSet = true;
            return this;
        }

        @Override
        public PcepLabelMap getLabelMap() {
            return labelMap;
        }
    }

    /**
     * Reads PcepLabels from the byte stream received from channel buffer.
     *
     * @param cb of type channel buffer.
     * @return PcepLabelUpdate object.
     * @throws PcepParseException when fails to read from channel buffer
     */
    public static PcepLabelUpdate read(ChannelBuffer cb) throws PcepParseException {

        PcepLabelUpdateVer1 pceLabelUpdate = new PcepLabelUpdateVer1();

        PcepSrpObject srpObject;
        PcepObjectHeader tempObjHeader;

        //read SRP mandatory Object
        srpObject = PcepSrpObjectVer1.read(cb);

        //checking next object
        cb.markReaderIndex();

        tempObjHeader = PcepObjectHeader.read(cb);
        cb.resetReaderIndex();

        if (tempObjHeader.getObjClass() == PcepLspObjectVer1.LSP_OBJ_CLASS) {

            //now it is belong to <pce-label-download>
            PcepLabelDownload labelDownload = new PcepLabelDownload();

            //set SRP
            labelDownload.setSrpObject(srpObject);

            //read and set LSP
            labelDownload.setLspObject(PcepLspObjectVer1.read(cb));

            //<label-list>
            LinkedList<PcepLabelObject> llLabelList = new LinkedList<>();
            PcepLabelObject labelObject;

            while (0 < cb.readableBytes()) {

                cb.markReaderIndex();
                tempObjHeader = PcepObjectHeader.read(cb);
                cb.resetReaderIndex();

                if (tempObjHeader.getObjClass() != PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
                    break;
                }
                labelObject = PcepLabelObjectVer1.read(cb);
                llLabelList.add(labelObject);
            }
            labelDownload.setLabelList(llLabelList);
            pceLabelUpdate.setLabelDownload(labelDownload);
        } else if (tempObjHeader.getObjClass() == PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
            //belong to <pce-label-map>
            PcepLabelMap labelMap = new PcepLabelMap();

            //set SRP Object
            labelMap.setSrpObject(srpObject);

            //read and set Label Object
            labelMap.setLabelObject(PcepLabelObjectVer1.read(cb));

            cb.markReaderIndex();
            tempObjHeader = PcepObjectHeader.read(cb);
            cb.resetReaderIndex();

            PcepFecObject fecObject = null;
            switch (tempObjHeader.getObjType()) {
            case PcepFecObjectIPv4Ver1.FEC_OBJ_TYPE:
                fecObject = PcepFecObjectIPv4Ver1.read(cb);
                break;
            case PcepFecObjectIPv6Ver1.FEC_OBJ_TYPE:
                fecObject = PcepFecObjectIPv6Ver1.read(cb);
                break;
            case PcepFecObjectIPv4AdjacencyVer1.FEC_OBJ_TYPE:
                fecObject = PcepFecObjectIPv4AdjacencyVer1.read(cb);
                break;
            case PcepFecObjectIPv6AdjacencyVer1.FEC_OBJ_TYPE:
                fecObject = PcepFecObjectIPv6AdjacencyVer1.read(cb);
                break;
            case PcepFecObjectIPv4UnnumberedAdjacencyVer1.FEC_OBJ_TYPE:
                fecObject = PcepFecObjectIPv4UnnumberedAdjacencyVer1.read(cb);
                break;
            default:
                throw new PcepParseException("Unkown FEC object type " + tempObjHeader.getObjType());
            }
            labelMap.setFECObject(fecObject);
            pceLabelUpdate.setLabelMap(labelMap);
        } else {
            throw new PcepParseException(
                    "Either <pce-label-download> or <pce-label-map> should be present. Received Class: "
                            + tempObjHeader.getObjClass());
        }
        return pceLabelUpdate;
    }

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

        if ((labelDownload != null) && (labelMap != null)) {
            throw new PcepParseException("Label Download and Label Map both can't be present.");
        }

        if ((labelDownload == null) && (labelMap == null)) {
            throw new PcepParseException("Either Label Download or Label Map should be present.");
        }

        if (labelDownload != null) {

            PcepLspObject lspObject;
            PcepSrpObject srpObject;
            PcepLabelObject labelObject;
            LinkedList<PcepLabelObject> llLabelList;

            srpObject = labelDownload.getSrpObject();
            if (srpObject == null) {
                throw new PcepParseException("SRP Object is mandatory object for Label Download.");
            } else {
                srpObject.write(cb);
            }

            lspObject = labelDownload.getLspObject();
            if (lspObject == null) {
                throw new PcepParseException("LSP Object is mandatory object for Label Download.");
            } else {
                lspObject.write(cb);
            }

            llLabelList = labelDownload.getLabelList();
            if (llLabelList == null) {
                throw new PcepParseException("Label list is mandatory object for Label Download.");
            } else {
                ListIterator<PcepLabelObject> listIterator = llLabelList.listIterator();
                while (listIterator.hasNext()) {
                    labelObject = listIterator.next();
                    labelObject.write(cb);
                }
            }
        }

        if (labelMap != null) {

            PcepSrpObject srpObject;
            PcepLabelObject labelObject;
            PcepFecObject fecObject;

            srpObject = labelMap.getSrpObject();
            if (srpObject == null) {
                throw new PcepParseException("SRP Object is mandatory object for Label map.");
            } else {
                srpObject.write(cb);
            }
            labelObject = labelMap.getLabelObject();
            if (labelObject == null) {
                throw new PcepParseException("label Object is mandatory object for Label map.");
            } else {
                labelObject.write(cb);
            }
            fecObject = labelMap.getFECObject();
            if (fecObject == null) {
                throw new PcepParseException("fec Object is mandatory object for Label map.");
            } else {
                fecObject.write(cb);
            }
        }
    }

    @Override
    public void setLabelDownload(PcepLabelDownload labelDownload) {
        if (this.isLabelMapSet) {
            return;
        }
        this.labelDownload = labelDownload;
        this.isLabelDownloadSet = true;
    }

    @Override
    public PcepLabelDownload getLabelDownload() {
        return this.labelDownload;
    }

    @Override
    public void setLabelMap(PcepLabelMap labelMap) {
        if (this.isLabelDownloadSet) {
            return;
        }
        this.labelMap = labelMap;
        this.isLabelMapSet = true;
    }

    @Override
    public PcepLabelMap getLabelMap() {
        return this.labelMap;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("LabelDownload", labelDownload)
                .add("LabelMap", labelMap)
                .toString();
    }
}
