/*
 * 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.types;

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.PcepErrorObject;
import org.onosproject.pcepio.protocol.PcepOpenObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provide the error object list with open object.
 */
public class ErrorObjListWithOpen {
    //errorObjList is mandatory
    private LinkedList<PcepErrorObject> llerrorObjList;
    // openObject is optional
    private PcepOpenObject openObject;
    // flag to check if open object is set or not
    private boolean isOpenObjectSet;
    protected static final Logger log = LoggerFactory.getLogger(ErrorObjListWithOpen.class);

    /**
     * Constructor to initialize Error and OPEN object.
     *
     * @param errObj ERROR object list
     * @param openObj OPEN object
     */
    public ErrorObjListWithOpen(LinkedList<PcepErrorObject> errObj, PcepOpenObject openObj) {
        this.llerrorObjList = errObj;
        this.openObject = openObj;
        if (openObj != null) {
            isOpenObjectSet = true;
        } else {
            isOpenObjectSet = false;
        }
    }

    /**
     * Constructor to initialize ERROR Object.
     *
     * @param errObj ERROR Object list
     */
    public ErrorObjListWithOpen(LinkedList<PcepErrorObject> errObj) {
        this.llerrorObjList = errObj;
        this.openObject = null;
        isOpenObjectSet = false;
    }

    /**
     * Return list of Error Types.
     *
     * @return error types list
     */
    public LinkedList<Integer> getErrorType() {
        LinkedList<Integer> errorType = new LinkedList<>();
        if (llerrorObjList != null) {
            ListIterator<PcepErrorObject> errObjListIterator = llerrorObjList.listIterator();
            int error;
            PcepErrorObject errorObj;
            while (errObjListIterator.hasNext()) {
                errorObj = errObjListIterator.next();
                error = errorObj.getErrorType();
                errorType.add(error);
            }
        }
        return errorType;
    }

    /**
     * Return list of Error Values.
     *
     * @return error values list
     */
    public LinkedList<Integer> getErrorValue() {
        LinkedList<Integer> errorValue = new LinkedList<>();
        if (llerrorObjList != null) {
            ListIterator<PcepErrorObject> errObjListIterator = llerrorObjList.listIterator();
            int error;
            PcepErrorObject errorObj;
            while (errObjListIterator.hasNext()) {
                errorObj = errObjListIterator.next();
                error = errorObj.getErrorValue();
                errorValue.add(error);
            }
        }
        return errorValue;
    }

    /**
     * Checks whether ERROR Object list is empty or not.
     *
     * @return true if ERROR Object list is empty otherwise false
     */
    public boolean isErrorObjListWithOpenPresent() {
        // ( <error-obj-list> [<Open>]
        // At least in this case <error-obj-list> should be present.
        return !this.llerrorObjList.isEmpty();
    }

    /**
     * Write Error Object List and Open Object to channel buffer.
     *
     * @param cb output channel buffer
     * @return length of written Error object list with open
     * @throws PcepParseException when mandatory fields are not set
     */
    public int write(ChannelBuffer cb) throws PcepParseException {
        int iLenStartIndex = cb.writerIndex();
        boolean bIsErrObjListFound = false;

        //<error-obj-list> is mandatory , if not present throw exception.
        if (llerrorObjList != null) {
            ListIterator<PcepErrorObject> errObjListIterator = llerrorObjList.listIterator();
            while (errObjListIterator.hasNext()) {
                errObjListIterator.next().write(cb);
                bIsErrObjListFound = true;
            }
        }

        if (!bIsErrObjListFound) {
            throw new PcepParseException("<error-obj-list> is mandatory.");
        }

        //Open Object is optional , if present write.
        if (openObject != null) {
            openObject.write(cb);
        }

        return cb.writerIndex() - iLenStartIndex;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("ErrorObjList", llerrorObjList)
                .add("Open", openObject)
                .toString();
    }
}
