// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_CONTINUATION_FRAME = 0x09;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_DATA_FRAME = 0x00;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_DEFAULT_DEPENDENCY = 0;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_DEFAULT_WEIGHT = 16;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_ACK = 0x01;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_END_HEADERS = 0x04;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_END_STREAM = 0x01;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_PRIORITY = 0x20;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_FRAME_HEADER_SIZE = 9;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_GOAWAY_FRAME = 0x07;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_HEADERS_FRAME = 0x01;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_MAX_LENGTH = 0x4000; // Initial MAX_FRAME_SIZE value is 2^14
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_PING_FRAME = 0x06;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_PRIORITY_FRAME = 0x02;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_PUSH_PROMISE_FRAME = 0x05;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_RST_STREAM_FRAME = 0x03;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_SETTINGS_FRAME = 0x04;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_WINDOW_UPDATE_FRAME = 0x08;


import java.util.Set;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import static com.twitter.http2.HttpCodecUtil.HTTP_CONTINUATION_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_DATA_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_DEFAULT_DEPENDENCY;
import static com.twitter.http2.HttpCodecUtil.HTTP_DEFAULT_WEIGHT;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_ACK;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_END_HEADERS;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_END_STREAM;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_PRIORITY;
import static com.twitter.http2.HttpCodecUtil.HTTP_FRAME_HEADER_SIZE;
import static com.twitter.http2.HttpCodecUtil.HTTP_GOAWAY_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_HEADERS_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_MAX_LENGTH;
import static com.twitter.http2.HttpCodecUtil.HTTP_PING_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_PRIORITY_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_PUSH_PROMISE_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_RST_STREAM_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_SETTINGS_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_WINDOW_UPDATE_FRAME;
        writeFrameHeader(frame, length, HTTP_RST_STREAM_FRAME, flags, streamId);
        frame.writeInt(errorCode);
        return frame;
    }

    /**
     * Encode an HTTP/2 SETTINGS Frame
     */
    public ByteBuf encodeSettingsFrame(HttpSettingsFrame httpSettingsFrame) {
        Set<Integer> ids = httpSettingsFrame.getIds();
        int length = ids.size() * 6;
        byte flags = httpSettingsFrame.isAck() ? HTTP_FLAG_ACK : 0;
        int streamId = 0;
        ByteBuf frame = Unpooled.buffer(HTTP_FRAME_HEADER_SIZE + length);
        writeFrameHeader(frame, length, HTTP_SETTINGS_FRAME, flags, streamId);
        for (int id : ids) {
            frame.writeShort(id);
            frame.writeInt(httpSettingsFrame.getValue(id));
        }
        return frame;
    }

    /**
     * Encode an HTTP/2 PUSH_PROMISE Frame
     */
    public ByteBuf encodePushPromiseFrame(int streamId, int promisedStreamId, ByteBuf headerBlock) {
        boolean needsContinuations = headerBlock.readableBytes() > HTTP_MAX_LENGTH - 4;
        int length = needsContinuations ? HTTP_MAX_LENGTH - 4 : headerBlock.readableBytes();
        byte flags = needsContinuations ? 0 : HTTP_FLAG_END_HEADERS;
        ByteBuf header = Unpooled.buffer(HTTP_FRAME_HEADER_SIZE + 4);
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_CONTINUATION_FRAME = 0x09;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_DATA_FRAME = 0x00;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_DEFAULT_DEPENDENCY = 0;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_DEFAULT_WEIGHT = 16;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_ACK = 0x01;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_END_HEADERS = 0x04;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_END_STREAM = 0x01;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final byte HTTP_FLAG_PRIORITY = 0x20;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_FRAME_HEADER_SIZE = 9;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_GOAWAY_FRAME = 0x07;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_HEADERS_FRAME = 0x01;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_MAX_LENGTH = 0x4000; // Initial MAX_FRAME_SIZE value is 2^14
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_PING_FRAME = 0x06;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_PRIORITY_FRAME = 0x02;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_PUSH_PROMISE_FRAME = 0x05;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_RST_STREAM_FRAME = 0x03;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_SETTINGS_FRAME = 0x04;
// 
// Path: src/main/java/com/twitter/http2/HttpCodecUtil.java
// static final int HTTP_WINDOW_UPDATE_FRAME = 0x08;


// Path: src/main/java/com/twitter/http2/HttpFrameEncoder.java
import java.util.Set;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import static com.twitter.http2.HttpCodecUtil.HTTP_CONTINUATION_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_DATA_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_DEFAULT_DEPENDENCY;
import static com.twitter.http2.HttpCodecUtil.HTTP_DEFAULT_WEIGHT;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_ACK;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_END_HEADERS;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_END_STREAM;
import static com.twitter.http2.HttpCodecUtil.HTTP_FLAG_PRIORITY;
import static com.twitter.http2.HttpCodecUtil.HTTP_FRAME_HEADER_SIZE;
import static com.twitter.http2.HttpCodecUtil.HTTP_GOAWAY_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_HEADERS_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_MAX_LENGTH;
import static com.twitter.http2.HttpCodecUtil.HTTP_PING_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_PRIORITY_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_PUSH_PROMISE_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_RST_STREAM_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_SETTINGS_FRAME;
import static com.twitter.http2.HttpCodecUtil.HTTP_WINDOW_UPDATE_FRAME;

        writeFrameHeader(frame, length, HTTP_RST_STREAM_FRAME, flags, streamId);
        frame.writeInt(errorCode);
        return frame;
    }

    /**
     * Encode an HTTP/2 SETTINGS Frame
     */
    public ByteBuf encodeSettingsFrame(HttpSettingsFrame httpSettingsFrame) {
        Set<Integer> ids = httpSettingsFrame.getIds();
        int length = ids.size() * 6;
        byte flags = httpSettingsFrame.isAck() ? HTTP_FLAG_ACK : 0;
        int streamId = 0;
        ByteBuf frame = Unpooled.buffer(HTTP_FRAME_HEADER_SIZE + length);
        writeFrameHeader(frame, length, HTTP_SETTINGS_FRAME, flags, streamId);
        for (int id : ids) {
            frame.writeShort(id);
            frame.writeInt(httpSettingsFrame.getValue(id));
        }
        return frame;
    }

    /**
     * Encode an HTTP/2 PUSH_PROMISE Frame
     */
    public ByteBuf encodePushPromiseFrame(int streamId, int promisedStreamId, ByteBuf headerBlock) {
        boolean needsContinuations = headerBlock.readableBytes() > HTTP_MAX_LENGTH - 4;
        int length = needsContinuations ? HTTP_MAX_LENGTH - 4 : headerBlock.readableBytes();
        byte flags = needsContinuations ? 0 : HTTP_FLAG_END_HEADERS;
        ByteBuf header = Unpooled.buffer(HTTP_FRAME_HEADER_SIZE + 4);
        writeFrameHeader(header, length + 4, HTTP_PUSH_PROMISE_FRAME, flags, streamId);