// 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;
    }

    /**
     * Encode an HTTP/2 HEADERS Frame
     */
    public ByteBuf encodeHeadersFrame(
            int streamId,
            boolean endStream,
            boolean exclusive,
            int dependency,
            int weight,
            ByteBuf headerBlock
    ) {
        byte flags = endStream ? HTTP_FLAG_END_STREAM : 0;
        boolean hasPriority = exclusive
                || dependency != HTTP_DEFAULT_DEPENDENCY || weight != HTTP_DEFAULT_WEIGHT;
        if (hasPriority) {
            flags |= HTTP_FLAG_PRIORITY;
        }
        int maxLength = hasPriority ? HTTP_MAX_LENGTH - 5 : HTTP_MAX_LENGTH;
        boolean needsContinuations = headerBlock.readableBytes() > maxLength;
        if (!needsContinuations) {
            flags |= HTTP_FLAG_END_HEADERS;
        }
        int length = needsContinuations ? maxLength : headerBlock.readableBytes();
        if (hasPriority) {
            length += 5;
        }
        int frameLength = hasPriority ? HTTP_FRAME_HEADER_SIZE + 5 : HTTP_FRAME_HEADER_SIZE;
        ByteBuf header = Unpooled.buffer(frameLength);
// 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;

    }

    /**
     * Encode an HTTP/2 HEADERS Frame
     */
    public ByteBuf encodeHeadersFrame(
            int streamId,
            boolean endStream,
            boolean exclusive,
            int dependency,
            int weight,
            ByteBuf headerBlock
    ) {
        byte flags = endStream ? HTTP_FLAG_END_STREAM : 0;
        boolean hasPriority = exclusive
                || dependency != HTTP_DEFAULT_DEPENDENCY || weight != HTTP_DEFAULT_WEIGHT;
        if (hasPriority) {
            flags |= HTTP_FLAG_PRIORITY;
        }
        int maxLength = hasPriority ? HTTP_MAX_LENGTH - 5 : HTTP_MAX_LENGTH;
        boolean needsContinuations = headerBlock.readableBytes() > maxLength;
        if (!needsContinuations) {
            flags |= HTTP_FLAG_END_HEADERS;
        }
        int length = needsContinuations ? maxLength : headerBlock.readableBytes();
        if (hasPriority) {
            length += 5;
        }
        int frameLength = hasPriority ? HTTP_FRAME_HEADER_SIZE + 5 : HTTP_FRAME_HEADER_SIZE;
        ByteBuf header = Unpooled.buffer(frameLength);
        writeFrameHeader(header, length, HTTP_HEADERS_FRAME, flags, streamId);