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

import java.util.ArrayList;
import java.util.List;

import org.jboss.netty.buffer.ChannelBuffer;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFType;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionType;
import org.openflow.protocol.statistics.OFStatistics;
import org.openflow.protocol.statistics.OFStatisticsType;
import org.openflow.protocol.statistics.OFVendorStatistics;
import org.openflow.protocol.vendor.OFByteArrayVendorData;
import org.openflow.protocol.vendor.OFVendorData;
import org.openflow.protocol.vendor.OFVendorDataType;
import org.openflow.protocol.vendor.OFVendorId;


/**
 * A basic OpenFlow factory that supports naive creation of both Messages and
 * Actions.
 *
 * @author David Erickson (daviderickson@cs.stanford.edu)
 * @author Rob Sherwood (rob.sherwood@stanford.edu)
 *
 */
public class BasicFactory implements OFMessageFactory, OFActionFactory,
        OFStatisticsFactory, OFVendorDataFactory {
    @Override
    public OFMessage getMessage(OFType t) {
        return t.newInstance();
    }

    @Override
    public List<OFMessage> parseMessage(ChannelBuffer data) throws MessageParseException {
        List<OFMessage> msglist = new ArrayList<OFMessage>();
        OFMessage msg = null;

        while (data.readableBytes() >= OFMessage.MINIMUM_LENGTH) {
            data.markReaderIndex();
            msg = this.parseMessageOne(data);
            if (msg == null) {
                data.resetReaderIndex();
                break;
            }
            else {
                msglist.add(msg);
            }
        }

        if (msglist.size() == 0) {
            return null;
        }
        return msglist;

    }

    public OFMessage parseMessageOne(ChannelBuffer data) throws MessageParseException {
        try {
            OFMessage demux = new OFMessage();
            OFMessage ofm = null;

            if (data.readableBytes() < OFMessage.MINIMUM_LENGTH)
                return ofm;

            data.markReaderIndex();
            demux.readFrom(data);
            data.resetReaderIndex();

            if (demux.getLengthU() > data.readableBytes())
                return ofm;

            ofm = getMessage(demux.getType());
            if (ofm == null)
                return null;

            if (ofm instanceof OFActionFactoryAware) {
                ((OFActionFactoryAware)ofm).setActionFactory(this);
            }
            if (ofm instanceof OFMessageFactoryAware) {
                ((OFMessageFactoryAware)ofm).setMessageFactory(this);
            }
            if (ofm instanceof OFStatisticsFactoryAware) {
                ((OFStatisticsFactoryAware)ofm).setStatisticsFactory(this);
            }
            if (ofm instanceof OFVendorDataFactoryAware) {
                ((OFVendorDataFactoryAware)ofm).setVendorDataFactory(this);
            }
            ofm.readFrom(data);
            if (OFMessage.class.equals(ofm.getClass())) {
                // advance the position for un-implemented messages
                data.readerIndex(data.readerIndex()+(ofm.getLengthU() -
                        OFMessage.MINIMUM_LENGTH));
            }

            return ofm;
        } catch (Exception e) {
            /* Write the offending data along with the error message */
            data.resetReaderIndex();
            String msg =
                    "Message Parse Error for packet:" +  dumpBuffer(data) +
                    "\nException: " + e.toString();
            data.resetReaderIndex();

            throw new MessageParseException(msg, e);
        }
    }

    @Override
    public OFAction getAction(OFActionType t) {
        return t.newInstance();
    }

    @Override
    public List<OFAction> parseActions(ChannelBuffer data, int length) {
        return parseActions(data, length, 0);
    }

    @Override
    public List<OFAction> parseActions(ChannelBuffer data, int length, int limit) {
        List<OFAction> results = new ArrayList<OFAction>();
        OFAction demux = new OFAction();
        OFAction ofa;
        int end = data.readerIndex() + length;

        while (limit == 0 || results.size() <= limit) {
            if ((data.readableBytes() < OFAction.MINIMUM_LENGTH ||
                (data.readerIndex() + OFAction.MINIMUM_LENGTH) > end))
                return results;

            data.markReaderIndex();
            demux.readFrom(data);
            data.resetReaderIndex();

            if ((demux.getLengthU() > data.readableBytes() ||
                (data.readerIndex() + demux.getLengthU()) > end))
                return results;

            ofa = getAction(demux.getType());
            ofa.readFrom(data);
            if (OFAction.class.equals(ofa.getClass())) {
                // advance the position for un-implemented messages
                data.readerIndex(data.readerIndex()+(ofa.getLengthU() -
                        OFAction.MINIMUM_LENGTH));
            }
            results.add(ofa);
        }

        return results;
    }

    @Override
    public OFActionFactory getActionFactory() {
        return this;
    }

    @Override
    public OFStatistics getStatistics(OFType t, OFStatisticsType st) {
        return st.newInstance(t);
    }

    @Override
    public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
                                              ChannelBuffer data, int length) {
        return parseStatistics(t, st, data, length, 0);
    }

    /**
     * @param t
     *            OFMessage type: should be one of stats_request or stats_reply
     * @param st
     *            statistics type of this message, e.g., DESC, TABLE
     * @param data
     *            buffer to read from
     * @param length
     *            length of statistics
     * @param limit
     *            number of statistics to grab; 0 == all
     * 
     * @return list of statistics
     */

    @Override
    public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
            ChannelBuffer data, int length, int limit) {
        List<OFStatistics> results = new ArrayList<OFStatistics>();
        OFStatistics statistics = getStatistics(t, st);

        int start = data.readerIndex();
        int count = 0;

        while (limit == 0 || results.size() <= limit) {
            // TODO Create a separate MUX/DEMUX path for vendor stats
            if (statistics instanceof OFVendorStatistics)
                ((OFVendorStatistics)statistics).setLength(length);

            /**
             * can't use data.remaining() here, b/c there could be other data
             * buffered past this message
             */
            if ((length - count) >= statistics.getLength()) {
                if (statistics instanceof OFActionFactoryAware)
                    ((OFActionFactoryAware)statistics).setActionFactory(this);
                statistics.readFrom(data);
                results.add(statistics);
                count += statistics.getLength();
                statistics = getStatistics(t, st);
            } else {
                if (count < length) {
                    /**
                     * Nasty case: partial/incomplete statistic found even
                     * though we have a full message. Found when NOX sent
                     * agg_stats request with wrong agg statistics length (52
                     * instead of 56)
                     * 
                     * just throw the rest away, or we will break framing
                     */
                    data.readerIndex(start + length);
                }
                return results;
            }
        }
        return results; // empty; no statistics at all
    }


    @Override
    public OFVendorData getVendorData(OFVendorId vendorId,
                                      OFVendorDataType vendorDataType) {
        if (vendorDataType == null)
            return null;
        
        return vendorDataType.newInstance();
    }

    /**
     * Attempts to parse and return the OFVendorData contained in the given
     * ChannelBuffer, beginning right after the vendor id.
     * @param vendor the vendor id that was parsed from the OFVendor message.
     * @param data the ChannelBuffer from which to parse the vendor data
     * @param length the length to the end of the enclosing message.
     * @return an OFVendorData instance
     */
    public OFVendorData parseVendorData(int vendor, ChannelBuffer data,
            int length) {
        OFVendorDataType vendorDataType = null;
        OFVendorId vendorId = OFVendorId.lookupVendorId(vendor);
        if (vendorId != null) {
            data.markReaderIndex();
            vendorDataType = vendorId.parseVendorDataType(data, length);
            data.resetReaderIndex();
        }
        
        OFVendorData vendorData = getVendorData(vendorId, vendorDataType);
        if (vendorData == null)
            vendorData = new OFByteArrayVendorData();

        vendorData.readFrom(data, length);
        
        return vendorData;
    }

    public static String dumpBuffer(ChannelBuffer data) {
        // NOTE: Reads all the bytes in buffer from current read offset.
        // Set/Reset ReaderIndex if you want to read from a different location
        int len = data.readableBytes();
        StringBuffer sb = new StringBuffer();
        for (int i=0 ; i<len; i++) {
            if (i%32 == 0) sb.append("\n");
            if (i%4 == 0) sb.append(" ");
            sb.append(String.format("%02x", data.getUnsignedByte(i)));
        }
        return sb.toString();
    }

}
