/*
 * 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.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorInfo;
import org.onosproject.pcepio.protocol.PcepErrorObject;
import org.onosproject.pcepio.protocol.PcepRPObject;
import org.onosproject.pcepio.protocol.PcepTEObject;
import org.onosproject.pcepio.types.PcepObjectHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides PCEP Error Info.
 * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
 */
public class PcepErrorInfoVer1 implements PcepErrorInfo {

    protected static final Logger log = LoggerFactory.getLogger(PcepErrorInfoVer1.class);
    //Error list is optional
    private LinkedList<PcepError> errList;

    /**
     * Constructor to add PCEP error object to the list.
     *
     * @param llRPObjList list of PCEP RP object
     * @param llTEObjList list of PCEP TE object
     * @param llErrObjList list of PCEP error object
     */
    public PcepErrorInfoVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
            LinkedList<PcepErrorObject> llErrObjList) {
        this.errList = new LinkedList<PcepError>();
        if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
            this.errList.add(new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList));
        }
    }

    /**
     * Constructor to initialize error info.
     *
     * @param errll linked list or pcep error
     */
    public PcepErrorInfoVer1(LinkedList<PcepError> errll) {
        this.errList = errll;
    }

    @Override
    public boolean isErrorInfoPresent() {
        return (!this.errList.isEmpty()) ? true : false;
    }

    @Override
    public void read(ChannelBuffer cb) throws PcepParseException {
        PcepObjectHeader tempObjHeader;

        while (0 < cb.readableBytes()) {
            cb.markReaderIndex();
            tempObjHeader = PcepObjectHeader.read(cb);
            cb.resetReaderIndex();
            byte yObjClass = tempObjHeader.getObjClass();
            if ((yObjClass != PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjClass != PcepTEObjectVer1.TE_OBJ_CLASS)
                    && (yObjClass != PcepErrorObjectVer1.ERROR_OBJ_CLASS)) {
                throw new PcepParseException("Unknown Object is present in PCEP-ERROR. Object Class: " + yObjClass);
            }

            this.errList.add(PcepErrorVer1.read(cb));
        }
    }

    @Override
    public void write(ChannelBuffer cb) throws PcepParseException {
        //write <error>
        ListIterator<PcepError> listIterator = errList.listIterator();
        while (listIterator.hasNext()) {
            PcepError pcepError = listIterator.next();

            //RP Object list is optional
            LinkedList<PcepRPObject> llRPObjList = pcepError.getRPObjList();
            if (llRPObjList != null) {
                ListIterator<PcepRPObject> rpListIterator = llRPObjList.listIterator();
                while (rpListIterator.hasNext()) {
                    rpListIterator.next().write(cb);
                }
            }

            //TE Object list is optional
            LinkedList<PcepTEObject> llTEObjList = pcepError.getTEObjList();
            if (llTEObjList != null) {
                ListIterator<PcepTEObject> teListIterator = llTEObjList.listIterator();
                while (teListIterator.hasNext()) {
                    teListIterator.next().write(cb);
                }
            }

            // <error-obj-list> is mandatory
            boolean bIsErrorObjListFound = false;

            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
            if (llErrObjList != null) {
                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
                while (errObjListIterator.hasNext()) {
                    errObjListIterator.next().write(cb);
                    bIsErrorObjListFound = true;
                }
            }

            if (!bIsErrorObjListFound) {
                throw new PcepParseException("<error-obj-list> is mandatory.");
            }
        }
    }

    @Override
    public LinkedList<Integer> getErrorType() {
        LinkedList<Integer> errorType = new LinkedList<Integer>();
        ListIterator<PcepError> listIterator = errList.listIterator();
        PcepErrorObject errObj;
        int error;
        while (listIterator.hasNext()) {
            PcepError pcepError = listIterator.next();
            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
            if (llErrObjList != null) {
                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
                while (errObjListIterator.hasNext()) {
                    errObj = errObjListIterator.next();
                    error = errObj.getErrorType();
                    errorType.add(error);
                }
            }
        }
        return errorType;
    }

    @Override
    public LinkedList<Integer> getErrorValue() {
        LinkedList<Integer> errorValue = new LinkedList<Integer>();
        ListIterator<PcepError> listIterator = errList.listIterator();
        PcepErrorObject errObj;
        int error;
        while (listIterator.hasNext()) {
            PcepError pcepError = listIterator.next();
            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
            if (llErrObjList != null) {
                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
                while (errObjListIterator.hasNext()) {
                    errObj = errObjListIterator.next();
                    error = errObj.getErrorValue();
                    errorValue.add(error);
                }
            }
        }
        return errorValue;
    }

    /**
     * Builder class for PCEP error info.
     */
    public static class Builder implements PcepErrorInfo.Builder {
        private LinkedList<PcepError> errll;

        @Override
        public PcepErrorInfo build() {
            return new PcepErrorInfoVer1(errll);
        }

        @Override
        public LinkedList<PcepError> getPcepErrorList() {
            return this.errll;
        }

        @Override
        public Builder setPcepErrorList(LinkedList<PcepError> errll) {
            this.errll = errll;
            return this;
        }
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass()).add("ErrorList", errList).toString();
    }
}
