/*
 * Copyright 2015-present 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();
    }
}
