/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 */

/*
 * This file is auto-generated by Qpid Gentools v.0.1 - do not modify.
 * Supported AMQP version:
 *   8-0
 */

package org.apache.qpid.framing;

import org.apache.qpid.QpidException;
import org.apache.qpid.bytebuffer.QpidByteBuffer;

public class ConnectionTuneOkBody extends AMQMethodBodyImpl implements EncodableAMQDataBlock, AMQMethodBody
{

    public static final int CLASS_ID =  10;
    public static final int METHOD_ID = 31;

    // Fields declared in specification
    private final int _channelMax; // [channelMax]
    private final long _frameMax; // [frameMax]
    private final int _heartbeat; // [heartbeat]

    public ConnectionTuneOkBody(
            int channelMax,
            long frameMax,
            int heartbeat
                               )
    {
        _channelMax = channelMax;
        _frameMax = frameMax;
        _heartbeat = heartbeat;
    }

    public int getClazz()
    {
        return CLASS_ID;
    }

    public int getMethod()
    {
        return METHOD_ID;
    }

    public final int getChannelMax()
    {
        return _channelMax;
    }
    public final long getFrameMax()
    {
        return _frameMax;
    }
    public final int getHeartbeat()
    {
        return _heartbeat;
    }

    protected int getBodySize()
    {
        int size = 8;
        return size;
    }

    public void writeMethodPayload(QpidByteBuffer buffer)
    {
        writeUnsignedShort( buffer, _channelMax );
        writeUnsignedInteger( buffer, _frameMax );
        writeUnsignedShort( buffer, _heartbeat );
    }

    public boolean execute(MethodDispatcher dispatcher, int channelId) throws QpidException
	{
        return dispatcher.dispatchConnectionTuneOk(this, channelId);
	}

    public String toString()
    {
        StringBuilder buf = new StringBuilder("[ConnectionTuneOkBodyImpl: ");
        buf.append( "channelMax=" );
        buf.append(  getChannelMax() );
        buf.append( ", " );
        buf.append( "frameMax=" );
        buf.append(  getFrameMax() );
        buf.append( ", " );
        buf.append( "heartbeat=" );
        buf.append(  getHeartbeat() );
        buf.append("]");
        return buf.toString();
    }

    public static void process(final QpidByteBuffer buffer, final ServerMethodProcessor dispatcher)
    {

        int channelMax = buffer.getUnsignedShort();
        long frameMax = buffer.getUnsignedInt();
        int heartbeat = buffer.getUnsignedShort();
        if(!dispatcher.ignoreAllButCloseOk())
        {
            dispatcher.receiveConnectionTuneOk(channelMax, frameMax, heartbeat);
        }
    }
}
