/*
 *
 * 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 java.nio.ByteBuffer;

import org.apache.qpid.QpidException;
import org.apache.qpid.util.ByteBufferUtils;

public class ConnectionTuneBody extends AMQMethodBodyImpl implements EncodableAMQDataBlock, AMQMethodBody
{

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

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

    public ConnectionTuneBody(
            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(ByteBuffer buffer)
    {
        writeUnsignedShort( buffer, _channelMax );
        writeUnsignedInteger( buffer, _frameMax );
        writeUnsignedShort( buffer, _heartbeat );
    }

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

    public String toString()
    {
        StringBuilder buf = new StringBuilder("[ConnectionTuneBodyImpl: ");
        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 ByteBuffer buffer, final ClientMethodProcessor dispatcher)
    {

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