/**
*    Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
*    University
* 
*    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.openflow.protocol;

import java.util.Arrays;
import java.util.List;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.openflow.protocol.factory.MessageParseException;
import org.openflow.protocol.factory.OFMessageFactory;
import org.openflow.protocol.factory.OFMessageFactoryAware;
import org.openflow.util.U16;

/**
 * Represents an ofp_error_msg
 * 
 * @author David Erickson (daviderickson@cs.stanford.edu)
 * @author Rob Sherwood (rob.sherwood@stanford.edu)
 */
public class OFError extends OFMessage implements OFMessageFactoryAware {
    public static int MINIMUM_LENGTH = 12;

    public enum OFErrorType {
        // OFPET_VENDOR_ERROR is an extension that was added in Open vSwitch and isn't
        // in the OF 1.0 spec, but it was easier to add it here instead of adding
        // generic support for extensible vendor-defined error messages. 
        // It uses the random value 0xb0c2 to avoid conflicts with other possible new
        // error types. Support for vendor-defined extended errors has been standardized
        // in the OF 1.2 spec, so this workaround is only needed for 1.0.
        OFPET_HELLO_FAILED, OFPET_BAD_REQUEST, OFPET_BAD_ACTION, OFPET_FLOW_MOD_FAILED, OFPET_PORT_MOD_FAILED, OFPET_QUEUE_OP_FAILED, OFPET_VENDOR_ERROR((short)0xb0c2);
        
        protected short value;
        
        private OFErrorType() {
            this.value = (short) this.ordinal();
        }
        
        private OFErrorType(short value) {
            this.value = value;
        }
        
        public short getValue() {
            return value;
        }
    }

    public enum OFHelloFailedCode {
        OFPHFC_INCOMPATIBLE, OFPHFC_EPERM
    }

    public enum OFBadRequestCode {
        OFPBRC_BAD_VERSION, OFPBRC_BAD_TYPE, OFPBRC_BAD_STAT, OFPBRC_BAD_VENDOR, OFPBRC_BAD_SUBTYPE, OFPBRC_EPERM, OFPBRC_BAD_LEN, OFPBRC_BUFFER_EMPTY, OFPBRC_BUFFER_UNKNOWN
    }

    public enum OFBadActionCode {
        OFPBAC_BAD_TYPE, OFPBAC_BAD_LEN, OFPBAC_BAD_VENDOR, OFPBAC_BAD_VENDOR_TYPE, OFPBAC_BAD_OUT_PORT, OFPBAC_BAD_ARGUMENT, OFPBAC_EPERM, OFPBAC_TOO_MANY, OFPBAC_BAD_QUEUE
    }

    public enum OFFlowModFailedCode {
        OFPFMFC_ALL_TABLES_FULL, OFPFMFC_OVERLAP, OFPFMFC_EPERM, OFPFMFC_BAD_EMERG_TIMEOUT, OFPFMFC_BAD_COMMAND, OFPFMFC_UNSUPPORTED
    }

    public enum OFPortModFailedCode {
        OFPPMFC_BAD_PORT, OFPPMFC_BAD_HW_ADDR
    }

    public enum OFQueueOpFailedCode {
        OFPQOFC_BAD_PORT, OFPQOFC_BAD_QUEUE, OFPQOFC_EPERM
    }

    protected short errorType;
    protected short errorCode;
    protected int vendor;
    protected int vendorErrorType;
    protected short vendorErrorCode;
    protected OFMessageFactory factory;
    protected byte[] error;
    protected boolean errorIsAscii;

    public OFError() {
        super();
        this.type = OFType.ERROR;
        this.length = U16.t(MINIMUM_LENGTH);
    }

    /**
     * @return the errorType
     */
    public short getErrorType() {
        return errorType;
    }

    /**
     * @param errorType
     *            the errorType to set
     */
    public void setErrorType(short errorType) {
        this.errorType = errorType;
    }

    public void setErrorType(OFErrorType type) {
        this.errorType = type.getValue();
    }

    /**
     * @return true if the error is an extended vendor error
     */
    public boolean isVendorError() {
        return errorType == OFErrorType.OFPET_VENDOR_ERROR.getValue();
    }
    
    /**
     * @return the errorCode
     */
    public short getErrorCode() {
        return errorCode;
    }

    /**
     * @param errorCode
     *            the errorCode to set
     */
    public void setErrorCode(OFHelloFailedCode code) {
        this.errorCode = (short) code.ordinal();
    }

    public void setErrorCode(short errorCode) {
        this.errorCode = errorCode;
    }

    public void setErrorCode(OFBadRequestCode code) {
        this.errorCode = (short) code.ordinal();
    }

    public void setErrorCode(OFBadActionCode code) {
        this.errorCode = (short) code.ordinal();
    }

    public void setErrorCode(OFFlowModFailedCode code) {
        this.errorCode = (short) code.ordinal();
    }

    public void setErrorCode(OFPortModFailedCode code) {
        this.errorCode = (short) code.ordinal();
    }

    public void setErrorCode(OFQueueOpFailedCode code) {
        this.errorCode = (short) code.ordinal();
    }

    public int getVendorErrorType() {
        return vendorErrorType;
    }
    
    public void setVendorErrorType(int vendorErrorType) {
        this.vendorErrorType = vendorErrorType;
    }
    
    public short getVendorErrorCode() {
        return vendorErrorCode;
    }
    
    public void setVendorErrorCode(short vendorErrorCode) {
        this.vendorErrorCode = vendorErrorCode;
    }
    
    public OFMessage getOffendingMsg() throws MessageParseException {
        // should only have one message embedded; if more than one, just
        // grab first
        if (this.error == null)
            return null;
        ChannelBuffer errorMsg = ChannelBuffers.wrappedBuffer(this.error);
        if (factory == null)
            throw new RuntimeException("MessageFactory not set");

        List<OFMessage> msglist = this.factory.parseMessage(errorMsg);
        if (msglist == null)
                return null;
        return msglist.get(0);
    }

    /**
     * Write this offending message into the payload of the Error message
     * 
     * @param offendingMsg
     */

    public void setOffendingMsg(OFMessage offendingMsg) {
        if (offendingMsg == null) {
            super.setLengthU(MINIMUM_LENGTH);
        } else {
            this.error = new byte[offendingMsg.getLengthU()];
            ChannelBuffer data = ChannelBuffers.wrappedBuffer(this.error);
            data.writerIndex(0);
            offendingMsg.writeTo(data);
            super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
        }
    }

    public OFMessageFactory getFactory() {
        return factory;
    }

    @Override
    public void setMessageFactory(OFMessageFactory factory) {
        this.factory = factory;
    }

    /**
     * @return the error
     */
    public byte[] getError() {
        return error;
    }

    /**
     * @param error
     *            the error to set
     */
    public void setError(byte[] error) {
        this.error = error;
    }

    /**
     * @return the errorIsAscii
     */
    public boolean isErrorIsAscii() {
        return errorIsAscii;
    }

    /**
     * @param errorIsAscii
     *            the errorIsAscii to set
     */
    public void setErrorIsAscii(boolean errorIsAscii) {
        this.errorIsAscii = errorIsAscii;
    }

    @Override
    public void readFrom(ChannelBuffer data) {
        super.readFrom(data);
        this.errorType = data.readShort();
        this.errorCode = data.readShort();
        int dataLength = this.getLengthU() - MINIMUM_LENGTH;
        if (dataLength > 0) {
            this.error = new byte[dataLength];
            data.readBytes(this.error);
            if (this.errorType == OFErrorType.OFPET_HELLO_FAILED.getValue())
                this.errorIsAscii = true;
        }
    }

    @Override
    public void writeTo(ChannelBuffer data) {
        super.writeTo(data);
        data.writeShort(errorType);
        data.writeShort(errorCode);
        if (error != null)
            data.writeBytes(error);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + Arrays.hashCode(error);
        result = prime * result + errorCode;
        result = prime * result + (errorIsAscii ? 1231 : 1237);
        result = prime * result + errorType;
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        OFError other = (OFError) obj;
        if (!Arrays.equals(error, other.error))
            return false;
        if (errorCode != other.errorCode)
            return false;
        if (errorIsAscii != other.errorIsAscii)
            return false;
        if (errorType != other.errorType)
            return false;
        return true;
    }

}
