/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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>]
     */
    private 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);
            }

            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 || llLabelList.isEmpty()) {
                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();
    }
}
