/*
 *
 * 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 ChannelAlertBody extends AMQMethodBodyImpl implements EncodableAMQDataBlock, AMQMethodBody
{

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

    // Fields declared in specification
    private final int _replyCode; // [replyCode]
    private final AMQShortString _replyText; // [replyText]
    private final FieldTable _details; // [details]

    public ChannelAlertBody(
            int replyCode,
            AMQShortString replyText,
            FieldTable details
                           )
    {
        _replyCode = replyCode;
        _replyText = replyText;
        _details = details;
    }

    public int getClazz()
    {
        return CLASS_ID;
    }

    public int getMethod()
    {
        return METHOD_ID;
    }

    public final int getReplyCode()
    {
        return _replyCode;
    }
    public final AMQShortString getReplyText()
    {
        return _replyText;
    }
    public final FieldTable getDetails()
    {
        return _details;
    }

    protected int getBodySize()
    {
        int size = 2;
        size += getSizeOf( _replyText );
        size += getSizeOf( _details );
        return size;
    }

    public void writeMethodPayload(QpidByteBuffer buffer)
    {
        writeUnsignedShort( buffer, _replyCode );
        writeAMQShortString( buffer, _replyText );
        writeFieldTable( buffer, _details );
    }

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

    public String toString()
    {
        StringBuilder buf = new StringBuilder("[ChannelAlertBodyImpl: ");
        buf.append( "replyCode=" );
        buf.append(  getReplyCode() );
        buf.append( ", " );
        buf.append( "replyText=" );
        buf.append(  getReplyText() );
        buf.append( ", " );
        buf.append( "details=" );
        buf.append(  getDetails() );
        buf.append("]");
        return buf.toString();
    }

    public static void process(final QpidByteBuffer buffer,
                               final ClientChannelMethodProcessor dispatcher)
            throws AMQFrameDecodingException
    {

        int replyCode = buffer.getUnsignedShort();
        AMQShortString replyText = AMQShortString.readAMQShortString(buffer);
        FieldTable details = EncodingUtils.readFieldTable(buffer);
        if(!dispatcher.ignoreAllButCloseOk())
        {
            dispatcher.receiveChannelAlert(replyCode, replyText, details);
        }
        if (details != null)
        {
            details.clearEncodedForm();
        }
    }
}
