/* Copyright 2015 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

package org.brotli.dec;

import static org.brotli.dec.RunningState.BLOCK_START;
import static org.brotli.dec.RunningState.CLOSED;
import static org.brotli.dec.RunningState.COMPRESSED_BLOCK_START;
import static org.brotli.dec.RunningState.COPY_LOOP;
import static org.brotli.dec.RunningState.COPY_UNCOMPRESSED;
import static org.brotli.dec.RunningState.COPY_WRAP_BUFFER;
import static org.brotli.dec.RunningState.FINISHED;
import static org.brotli.dec.RunningState.INSERT_LOOP;
import static org.brotli.dec.RunningState.MAIN_LOOP;
import static org.brotli.dec.RunningState.READ_METADATA;
import static org.brotli.dec.RunningState.TRANSFORM;
import static org.brotli.dec.RunningState.UNINITIALIZED;
import static org.brotli.dec.RunningState.WRITE;

/**
 * API for Brotli decompression.
 */
final class Decode {

  private static final int DEFAULT_CODE_LENGTH = 8;
  private static final int CODE_LENGTH_REPEAT_CODE = 16;
  private static final int NUM_LITERAL_CODES = 256;
  private static final int NUM_INSERT_AND_COPY_CODES = 704;
  private static final int NUM_BLOCK_LENGTH_CODES = 26;
  private static final int LITERAL_CONTEXT_BITS = 6;
  private static final int DISTANCE_CONTEXT_BITS = 2;

  private static final int HUFFMAN_TABLE_BITS = 8;
  private static final int HUFFMAN_TABLE_MASK = 0xFF;

  private static final int CODE_LENGTH_CODES = 18;
  private static final int[] CODE_LENGTH_CODE_ORDER = {
      1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  };

  private static final int NUM_DISTANCE_SHORT_CODES = 16;
  private static final int[] DISTANCE_SHORT_CODE_INDEX_OFFSET = {
      3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2
  };

  private static final int[] DISTANCE_SHORT_CODE_VALUE_OFFSET = {
      0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3
  };

  /**
   * Static Huffman code for the code length code lengths.
   */
  private static final int[] FIXED_TABLE = {
      0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040001,
      0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040005
  };

  /**
   * Decodes a number in the range [0..255], by reading 1 - 11 bits.
   */
  private static int decodeVarLenUnsignedByte(BitReader br) {
    if (BitReader.readBits(br, 1) != 0) {
      int n = BitReader.readBits(br, 3);
      if (n == 0) {
        return 1;
      } else {
        return BitReader.readBits(br, n) + (1 << n);
      }
    }
    return 0;
  }

  private static void decodeMetaBlockLength(BitReader br, State state) {
    state.inputEnd = BitReader.readBits(br, 1) == 1;
    state.metaBlockLength = 0;
    state.isUncompressed = false;
    state.isMetadata = false;
    if (state.inputEnd && BitReader.readBits(br, 1) != 0) {
      return;
    }
    int sizeNibbles = BitReader.readBits(br, 2) + 4;
    if (sizeNibbles == 7) {
      state.isMetadata = true;
      if (BitReader.readBits(br, 1) != 0) {
        throw new BrotliRuntimeException("Corrupted reserved bit");
      }
      int sizeBytes = BitReader.readBits(br, 2);
      if (sizeBytes == 0) {
        return;
      }
      for (int i = 0; i < sizeBytes; i++) {
        int bits = BitReader.readBits(br, 8);
        if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) {
          throw new BrotliRuntimeException("Exuberant nibble");
        }
        state.metaBlockLength |= bits << (i * 8);
      }
    } else {
      for (int i = 0; i < sizeNibbles; i++) {
        int bits = BitReader.readBits(br, 4);
        if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) {
          throw new BrotliRuntimeException("Exuberant nibble");
        }
        state.metaBlockLength |= bits << (i * 4);
      }
    }
    state.metaBlockLength++;
    if (!state.inputEnd) {
      state.isUncompressed = BitReader.readBits(br, 1) == 1;
    }
  }

  /**
   * Decodes the next Huffman code from bit-stream.
   */
  private static int readSymbol(int[] table, int offset, BitReader br) {
    int val = (int) (br.accumulator >>> br.bitOffset);
    offset += val & HUFFMAN_TABLE_MASK;
    int bits = table[offset] >> 16;
    int sym = table[offset] & 0xFFFF;
    if (bits <= HUFFMAN_TABLE_BITS) {
      br.bitOffset += bits;
      return sym;
    }
    offset += sym;
    int mask = (1 << bits) - 1;
    offset += (val & mask) >>> HUFFMAN_TABLE_BITS;
    br.bitOffset += ((table[offset] >> 16) + HUFFMAN_TABLE_BITS);
    return table[offset] & 0xFFFF;
  }

  private static int readBlockLength(int[] table, int offset, BitReader br) {
    BitReader.fillBitWindow(br);
    int code = readSymbol(table, offset, br);
    int n = Prefix.BLOCK_LENGTH_N_BITS[code];
    return Prefix.BLOCK_LENGTH_OFFSET[code] + BitReader.readBits(br, n);
  }

  private static int translateShortCodes(int code, int[] ringBuffer, int index) {
    if (code < NUM_DISTANCE_SHORT_CODES) {
      index += DISTANCE_SHORT_CODE_INDEX_OFFSET[code];
      index &= 3;
      return ringBuffer[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[code];
    }
    return code - NUM_DISTANCE_SHORT_CODES + 1;
  }

  private static void moveToFront(int[] v, int index) {
    int value = v[index];
    for (; index > 0; index--) {
      v[index] = v[index - 1];
    }
    v[0] = value;
  }

  private static void inverseMoveToFrontTransform(byte[] v, int vLen) {
    int[] mtf = new int[256];
    for (int i = 0; i < 256; i++) {
      mtf[i] = i;
    }
    for (int i = 0; i < vLen; i++) {
      int index = v[i] & 0xFF;
      v[i] = (byte) mtf[index];
      if (index != 0) {
        moveToFront(mtf, index);
      }
    }
  }

  private static void readHuffmanCodeLengths(
      int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths, BitReader br) {
    int symbol = 0;
    int prevCodeLen = DEFAULT_CODE_LENGTH;
    int repeat = 0;
    int repeatCodeLen = 0;
    int space = 32768;
    int[] table = new int[32];

    Huffman.buildHuffmanTable(table, 0, 5, codeLengthCodeLengths, CODE_LENGTH_CODES);

    while (symbol < numSymbols && space > 0) {
      BitReader.readMoreInput(br);
      BitReader.fillBitWindow(br);
      int p = (int) ((br.accumulator >>> br.bitOffset)) & 31;
      br.bitOffset += table[p] >> 16;
      int codeLen = table[p] & 0xFFFF;
      if (codeLen < CODE_LENGTH_REPEAT_CODE) {
        repeat = 0;
        codeLengths[symbol++] = codeLen;
        if (codeLen != 0) {
          prevCodeLen = codeLen;
          space -= 32768 >> codeLen;
        }
      } else {
        int extraBits = codeLen - 14;
        int newLen = 0;
        if (codeLen == CODE_LENGTH_REPEAT_CODE) {
          newLen = prevCodeLen;
        }
        if (repeatCodeLen != newLen) {
          repeat = 0;
          repeatCodeLen = newLen;
        }
        int oldRepeat = repeat;
        if (repeat > 0) {
          repeat -= 2;
          repeat <<= extraBits;
        }
        repeat += BitReader.readBits(br, extraBits) + 3;
        int repeatDelta = repeat - oldRepeat;
        if (symbol + repeatDelta > numSymbols) {
          throw new BrotliRuntimeException("symbol + repeatDelta > numSymbols"); // COV_NF_LINE
        }
        for (int i = 0; i < repeatDelta; i++) {
          codeLengths[symbol++] = repeatCodeLen;
        }
        if (repeatCodeLen != 0) {
          space -= repeatDelta << (15 - repeatCodeLen);
        }
      }
    }
    if (space != 0) {
      throw new BrotliRuntimeException("Unused space"); // COV_NF_LINE
    }
    // TODO: Pass max_symbol to Huffman table builder instead?
    Utils.fillWithZeroes(codeLengths, symbol, numSymbols - symbol);
  }

  // TODO: Use specialized versions for smaller tables.
  static void readHuffmanCode(int alphabetSize, int[] table, int offset, BitReader br) {
    boolean ok = true;
    int simpleCodeOrSkip;
    BitReader.readMoreInput(br);
    // TODO: Avoid allocation.
    int[] codeLengths = new int[alphabetSize];
    simpleCodeOrSkip = BitReader.readBits(br, 2);
    if (simpleCodeOrSkip == 1) { // Read symbols, codes & code lengths directly.
      int maxBitsCounter = alphabetSize - 1;
      int maxBits = 0;
      int[] symbols = new int[4];
      int numSymbols = BitReader.readBits(br, 2) + 1;
      while (maxBitsCounter != 0) {
        maxBitsCounter >>= 1;
        maxBits++;
      }
      // TODO: uncomment when codeLengths is reused.
      // Utils.fillWithZeroes(codeLengths, 0, alphabetSize);
      for (int i = 0; i < numSymbols; i++) {
        symbols[i] = BitReader.readBits(br, maxBits) % alphabetSize;
        codeLengths[symbols[i]] = 2;
      }
      codeLengths[symbols[0]] = 1;
      switch (numSymbols) {
        case 1:
          break;
        case 2:
          ok = symbols[0] != symbols[1];
          codeLengths[symbols[1]] = 1;
          break;
        case 3:
          ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[1] != symbols[2];
          break;
        case 4:
        default:
          ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[0] != symbols[3]
              && symbols[1] != symbols[2] && symbols[1] != symbols[3] && symbols[2] != symbols[3];
          if (BitReader.readBits(br, 1) == 1) {
            codeLengths[symbols[2]] = 3;
            codeLengths[symbols[3]] = 3;
          } else {
            codeLengths[symbols[0]] = 2;
          }
          break;
      }
    } else { // Decode Huffman-coded code lengths.
      int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES];
      int space = 32;
      int numCodes = 0;
      for (int i = simpleCodeOrSkip; i < CODE_LENGTH_CODES && space > 0; i++) {
        int codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
        BitReader.fillBitWindow(br);
        int p = (int) (br.accumulator >>> br.bitOffset) & 15;
        // TODO: Demultiplex FIXED_TABLE.
        br.bitOffset += FIXED_TABLE[p] >> 16;
        int v = FIXED_TABLE[p] & 0xFFFF;
        codeLengthCodeLengths[codeLenIdx] = v;
        if (v != 0) {
          space -= (32 >> v);
          numCodes++;
        }
      }
      ok = (numCodes == 1 || space == 0);
      readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSize, codeLengths, br);
    }
    if (!ok) {
      throw new BrotliRuntimeException("Can't readHuffmanCode"); // COV_NF_LINE
    }
    Huffman.buildHuffmanTable(table, offset, HUFFMAN_TABLE_BITS, codeLengths, alphabetSize);
  }

  private static int decodeContextMap(int contextMapSize, byte[] contextMap, BitReader br) {
    BitReader.readMoreInput(br);
    int numTrees = decodeVarLenUnsignedByte(br) + 1;

    if (numTrees == 1) {
      Utils.fillWithZeroes(contextMap, 0, contextMapSize);
      return numTrees;
    }

    boolean useRleForZeros = BitReader.readBits(br, 1) == 1;
    int maxRunLengthPrefix = 0;
    if (useRleForZeros) {
      maxRunLengthPrefix = BitReader.readBits(br, 4) + 1;
    }
    int[] table = new int[Huffman.HUFFMAN_MAX_TABLE_SIZE];
    readHuffmanCode(numTrees + maxRunLengthPrefix, table, 0, br);
    for (int i = 0; i < contextMapSize; ) {
      BitReader.readMoreInput(br);
      BitReader.fillBitWindow(br);
      int code = readSymbol(table, 0, br);
      if (code == 0) {
        contextMap[i] = 0;
        i++;
      } else if (code <= maxRunLengthPrefix) {
        int reps = (1 << code) + BitReader.readBits(br, code);
        while (reps != 0) {
          if (i >= contextMapSize) {
            throw new BrotliRuntimeException("Corrupted context map"); // COV_NF_LINE
          }
          contextMap[i] = 0;
          i++;
          reps--;
        }
      } else {
        contextMap[i] = (byte) (code - maxRunLengthPrefix);
        i++;
      }
    }
    if (BitReader.readBits(br, 1) == 1) {
      inverseMoveToFrontTransform(contextMap, contextMapSize);
    }
    return numTrees;
  }

  private static void decodeBlockTypeAndLength(State state, int treeType) {
    final BitReader br = state.br;
    final int[] ringBuffers = state.blockTypeRb;
    final int offset = treeType * 2;
    BitReader.fillBitWindow(br);
    int blockType = readSymbol(
        state.blockTypeTrees, treeType * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
    state.blockLength[treeType] = readBlockLength(state.blockLenTrees,
        treeType * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);

    if (blockType == 1) {
      blockType = ringBuffers[offset + 1] + 1;
    } else if (blockType == 0) {
      blockType = ringBuffers[offset];
    } else {
      blockType -= 2;
    }
    if (blockType >= state.numBlockTypes[treeType]) {
      blockType -= state.numBlockTypes[treeType];
    }
    ringBuffers[offset] = ringBuffers[offset + 1];
    ringBuffers[offset + 1] = blockType;
  }

  private static void decodeLiteralBlockSwitch(State state) {
    decodeBlockTypeAndLength(state, 0);
    int literalBlockType = state.blockTypeRb[1];
    state.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS;
    state.literalTreeIndex = state.contextMap[state.contextMapSlice] & 0xFF;
    state.literalTree = state.hGroup0.trees[state.literalTreeIndex];
    int contextMode = state.contextModes[literalBlockType];
    state.contextLookupOffset1 = Context.LOOKUP_OFFSETS[contextMode];
    state.contextLookupOffset2 = Context.LOOKUP_OFFSETS[contextMode + 1];
  }

  private static void decodeCommandBlockSwitch(State state) {
    decodeBlockTypeAndLength(state, 1);
    state.treeCommandOffset = state.hGroup1.trees[state.blockTypeRb[3]];
  }

  private static void decodeDistanceBlockSwitch(State state) {
    decodeBlockTypeAndLength(state, 2);
    state.distContextMapSlice = state.blockTypeRb[5] << DISTANCE_CONTEXT_BITS;
  }

  private static void maybeReallocateRingBuffer(State state) {
    int newSize = state.maxRingBufferSize;
    if ((long) newSize > state.expectedTotalSize) {
      /* TODO: Handle 2GB+ cases more gracefully. */
      int minimalNewSize = (int) state.expectedTotalSize + state.customDictionary.length;
      while ((newSize >> 1) > minimalNewSize) {
        newSize >>= 1;
      }
      if (!state.inputEnd && newSize < 16384 && state.maxRingBufferSize >= 16384) {
        newSize = 16384;
      }
    }
    if (newSize <= state.ringBufferSize) {
      return;
    }
    int ringBufferSizeWithSlack = newSize + Dictionary.MAX_TRANSFORMED_WORD_LENGTH;
    byte[] newBuffer = new byte[ringBufferSizeWithSlack];
    if (state.ringBuffer != null) {
      System.arraycopy(state.ringBuffer, 0, newBuffer, 0, state.ringBufferSize);
    } else {
      /* Prepend custom dictionary, if any. */
      if (state.customDictionary.length != 0) {
        int length = state.customDictionary.length;
        int offset = 0;
        if (length > state.maxBackwardDistance) {
          offset = length - state.maxBackwardDistance;
          length = state.maxBackwardDistance;
        }
        System.arraycopy(state.customDictionary, offset, newBuffer, 0, length);
        state.pos = length;
        state.bytesToIgnore = length;
      }
    }
    state.ringBuffer = newBuffer;
    state.ringBufferSize = newSize;
  }

  /**
   * Reads next metablock header.
   *
   * @param state decoding state
   */
  private static void readMetablockInfo(State state) {
    final BitReader br = state.br;

    if (state.inputEnd) {
      state.nextRunningState = FINISHED;
      state.bytesToWrite = state.pos;
      state.bytesWritten = 0;
      state.runningState = WRITE;
      return;
    }
    // TODO: Reset? Do we need this?
    state.hGroup0.codes = null;
    state.hGroup0.trees = null;
    state.hGroup1.codes = null;
    state.hGroup1.trees = null;
    state.hGroup2.codes = null;
    state.hGroup2.trees = null;

    BitReader.readMoreInput(br);
    decodeMetaBlockLength(br, state);
    if (state.metaBlockLength == 0 && !state.isMetadata) {
      return;
    }
    if (state.isUncompressed || state.isMetadata) {
      BitReader.jumpToByteBoundary(br);
      state.runningState = state.isMetadata ? READ_METADATA : COPY_UNCOMPRESSED;
    } else {
      state.runningState = COMPRESSED_BLOCK_START;
    }

    if (state.isMetadata) {
      return;
    }
    state.expectedTotalSize += state.metaBlockLength;
    if (state.ringBufferSize < state.maxRingBufferSize) {
      maybeReallocateRingBuffer(state);
    }
  }

  private static void readMetablockHuffmanCodesAndContextMaps(State state) {
    final BitReader br = state.br;

    for (int i = 0; i < 3; i++) {
      state.numBlockTypes[i] = decodeVarLenUnsignedByte(br) + 1;
      state.blockLength[i] = 1 << 28;
      if (state.numBlockTypes[i] > 1) {
        readHuffmanCode(state.numBlockTypes[i] + 2, state.blockTypeTrees,
            i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
        readHuffmanCode(NUM_BLOCK_LENGTH_CODES, state.blockLenTrees,
            i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
        state.blockLength[i] = readBlockLength(state.blockLenTrees,
            i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br);
      }
    }

    BitReader.readMoreInput(br);
    state.distancePostfixBits = BitReader.readBits(br, 2);
    state.numDirectDistanceCodes =
        NUM_DISTANCE_SHORT_CODES + (BitReader.readBits(br, 4) << state.distancePostfixBits);
    state.distancePostfixMask = (1 << state.distancePostfixBits) - 1;
    int numDistanceCodes = state.numDirectDistanceCodes + (48 << state.distancePostfixBits);
    // TODO: Reuse?
    state.contextModes = new byte[state.numBlockTypes[0]];
    for (int i = 0; i < state.numBlockTypes[0];) {
      /* Ensure that less than 256 bits read between readMoreInput. */
      int limit = Math.min(i + 96, state.numBlockTypes[0]);
      for (; i < limit; ++i) {
        state.contextModes[i] = (byte) (BitReader.readBits(br, 2) << 1);
      }
      BitReader.readMoreInput(br);
    }

    // TODO: Reuse?
    state.contextMap = new byte[state.numBlockTypes[0] << LITERAL_CONTEXT_BITS];
    int numLiteralTrees = decodeContextMap(state.numBlockTypes[0] << LITERAL_CONTEXT_BITS,
        state.contextMap, br);
    state.trivialLiteralContext = true;
    for (int j = 0; j < state.numBlockTypes[0] << LITERAL_CONTEXT_BITS; j++) {
      if (state.contextMap[j] != j >> LITERAL_CONTEXT_BITS) {
        state.trivialLiteralContext = false;
        break;
      }
    }

    // TODO: Reuse?
    state.distContextMap = new byte[state.numBlockTypes[2] << DISTANCE_CONTEXT_BITS];
    int numDistTrees = decodeContextMap(state.numBlockTypes[2] << DISTANCE_CONTEXT_BITS,
        state.distContextMap, br);

    HuffmanTreeGroup.init(state.hGroup0, NUM_LITERAL_CODES, numLiteralTrees);
    HuffmanTreeGroup.init(state.hGroup1, NUM_INSERT_AND_COPY_CODES, state.numBlockTypes[1]);
    HuffmanTreeGroup.init(state.hGroup2, numDistanceCodes, numDistTrees);

    HuffmanTreeGroup.decode(state.hGroup0, br);
    HuffmanTreeGroup.decode(state.hGroup1, br);
    HuffmanTreeGroup.decode(state.hGroup2, br);

    state.contextMapSlice = 0;
    state.distContextMapSlice = 0;
    state.contextLookupOffset1 = Context.LOOKUP_OFFSETS[state.contextModes[0]];
    state.contextLookupOffset2 = Context.LOOKUP_OFFSETS[state.contextModes[0] + 1];
    state.literalTreeIndex = 0;
    state.literalTree = state.hGroup0.trees[0];
    state.treeCommandOffset = state.hGroup1.trees[0]; // TODO: == 0?

    state.blockTypeRb[0] = state.blockTypeRb[2] = state.blockTypeRb[4] = 1;
    state.blockTypeRb[1] = state.blockTypeRb[3] = state.blockTypeRb[5] = 0;
  }

  private static void copyUncompressedData(State state) {
    final BitReader br = state.br;
    final byte[] ringBuffer = state.ringBuffer;

    // Could happen if block ends at ring buffer end.
    if (state.metaBlockLength <= 0) {
      BitReader.reload(br);
      state.runningState = BLOCK_START;
      return;
    }

    int chunkLength = Math.min(state.ringBufferSize - state.pos, state.metaBlockLength);
    BitReader.copyBytes(br, ringBuffer, state.pos, chunkLength);
    state.metaBlockLength -= chunkLength;
    state.pos += chunkLength;
    if (state.pos == state.ringBufferSize) {
        state.nextRunningState = COPY_UNCOMPRESSED;
        state.bytesToWrite = state.ringBufferSize;
        state.bytesWritten = 0;
        state.runningState = WRITE;
        return;
      }

    BitReader.reload(br);
    state.runningState = BLOCK_START;
  }

  private static boolean writeRingBuffer(State state) {
    /* Ignore custom dictionary bytes. */
    if (state.bytesToIgnore != 0) {
      state.bytesWritten += state.bytesToIgnore;
      state.bytesToIgnore = 0;
    }
    int toWrite = Math.min(state.outputLength - state.outputUsed,
        state.bytesToWrite - state.bytesWritten);
    if (toWrite != 0) {
      System.arraycopy(state.ringBuffer, state.bytesWritten, state.output,
          state.outputOffset + state.outputUsed, toWrite);
      state.outputUsed += toWrite;
      state.bytesWritten += toWrite;
    }

    return state.outputUsed < state.outputLength;
  }

  static void setCustomDictionary(State state, byte[] data) {
    state.customDictionary = (data == null) ? new byte[0] : data;
  }

  /**
   * Actual decompress implementation.
   */
  static void decompress(State state) {
    if (state.runningState == UNINITIALIZED) {
      throw new IllegalStateException("Can't decompress until initialized");
    }
    if (state.runningState == CLOSED) {
      throw new IllegalStateException("Can't decompress after close");
    }
    final BitReader br = state.br;
    int ringBufferMask = state.ringBufferSize - 1;
    byte[] ringBuffer = state.ringBuffer;

    while (state.runningState != FINISHED) {
      // TODO: extract cases to methods for the better readability.
      switch (state.runningState) {
        case BLOCK_START:
          if (state.metaBlockLength < 0) {
            throw new BrotliRuntimeException("Invalid metablock length");
          }
          readMetablockInfo(state);
          /* Ring-buffer would be reallocated here. */
          ringBufferMask = state.ringBufferSize - 1;
          ringBuffer = state.ringBuffer;
          continue;

        case COMPRESSED_BLOCK_START:
          readMetablockHuffmanCodesAndContextMaps(state);
          state.runningState = MAIN_LOOP;
          // Fall through

        case MAIN_LOOP:
          if (state.metaBlockLength <= 0) {
            state.runningState = BLOCK_START;
            continue;
          }
          BitReader.readMoreInput(br);
          if (state.blockLength[1] == 0) {
            decodeCommandBlockSwitch(state);
          }
          state.blockLength[1]--;
          BitReader.fillBitWindow(br);
          int cmdCode = readSymbol(state.hGroup1.codes, state.treeCommandOffset, br);
          int rangeIdx = cmdCode >>> 6;
          state.distanceCode = 0;
          if (rangeIdx >= 2) {
            rangeIdx -= 2;
            state.distanceCode = -1;
          }
          int insertCode = Prefix.INSERT_RANGE_LUT[rangeIdx] + ((cmdCode >>> 3) & 7);
          int copyCode = Prefix.COPY_RANGE_LUT[rangeIdx] + (cmdCode & 7);
          state.insertLength = Prefix.INSERT_LENGTH_OFFSET[insertCode] + BitReader
              .readBits(br, Prefix.INSERT_LENGTH_N_BITS[insertCode]);
          state.copyLength = Prefix.COPY_LENGTH_OFFSET[copyCode] + BitReader
              .readBits(br, Prefix.COPY_LENGTH_N_BITS[copyCode]);

          state.j = 0;
          state.runningState = INSERT_LOOP;

          // Fall through
        case INSERT_LOOP:
          if (state.trivialLiteralContext) {
            while (state.j < state.insertLength) {
              BitReader.readMoreInput(br);
              if (state.blockLength[0] == 0) {
                decodeLiteralBlockSwitch(state);
              }
              state.blockLength[0]--;
              BitReader.fillBitWindow(br);
              ringBuffer[state.pos] =
                  (byte) readSymbol(state.hGroup0.codes, state.literalTree, br);
              state.j++;
              if (state.pos++ == ringBufferMask) {
                state.nextRunningState = INSERT_LOOP;
                state.bytesToWrite = state.ringBufferSize;
                state.bytesWritten = 0;
                state.runningState = WRITE;
                break;
              }
            }
          } else {
            int prevByte1 = ringBuffer[(state.pos - 1) & ringBufferMask] & 0xFF;
            int prevByte2 = ringBuffer[(state.pos - 2) & ringBufferMask] & 0xFF;
            while (state.j < state.insertLength) {
              BitReader.readMoreInput(br);
              if (state.blockLength[0] == 0) {
                decodeLiteralBlockSwitch(state);
              }
              int literalTreeIndex = state.contextMap[state.contextMapSlice
                + (Context.LOOKUP[state.contextLookupOffset1 + prevByte1]
                    | Context.LOOKUP[state.contextLookupOffset2 + prevByte2])] & 0xFF;
              state.blockLength[0]--;
              prevByte2 = prevByte1;
              BitReader.fillBitWindow(br);
              prevByte1 = readSymbol(
                  state.hGroup0.codes, state.hGroup0.trees[literalTreeIndex], br);
              ringBuffer[state.pos] = (byte) prevByte1;
              state.j++;
              if (state.pos++ == ringBufferMask) {
                state.nextRunningState = INSERT_LOOP;
                state.bytesToWrite = state.ringBufferSize;
                state.bytesWritten = 0;
                state.runningState = WRITE;
                break;
              }
            }
          }
          if (state.runningState != INSERT_LOOP) {
            continue;
          }
          state.metaBlockLength -= state.insertLength;
          if (state.metaBlockLength <= 0) {
            state.runningState = MAIN_LOOP;
            continue;
          }
          if (state.distanceCode < 0) {
            BitReader.readMoreInput(br);
            if (state.blockLength[2] == 0) {
              decodeDistanceBlockSwitch(state);
            }
            state.blockLength[2]--;
            BitReader.fillBitWindow(br);
            state.distanceCode = readSymbol(state.hGroup2.codes, state.hGroup2.trees[
                state.distContextMap[state.distContextMapSlice
                    + (state.copyLength > 4 ? 3 : state.copyLength - 2)] & 0xFF], br);
            if (state.distanceCode >= state.numDirectDistanceCodes) {
              state.distanceCode -= state.numDirectDistanceCodes;
              int postfix = state.distanceCode & state.distancePostfixMask;
              state.distanceCode >>>= state.distancePostfixBits;
              int n = (state.distanceCode >>> 1) + 1;
              int offset = ((2 + (state.distanceCode & 1)) << n) - 4;
              state.distanceCode = state.numDirectDistanceCodes + postfix
                  + ((offset + BitReader.readBits(br, n)) << state.distancePostfixBits);
            }
          }

          // Convert the distance code to the actual distance by possibly looking up past distances
          // from the ringBuffer.
          state.distance = translateShortCodes(state.distanceCode, state.distRb, state.distRbIdx);
          if (state.distance < 0) {
            throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE
          }

          if (state.maxDistance != state.maxBackwardDistance
              && state.pos < state.maxBackwardDistance) {
            state.maxDistance = state.pos;
          } else {
            state.maxDistance = state.maxBackwardDistance;
          }

          state.copyDst = state.pos;
          if (state.distance > state.maxDistance) {
            state.runningState = TRANSFORM;
            continue;
          }

          if (state.distanceCode > 0) {
            state.distRb[state.distRbIdx & 3] = state.distance;
            state.distRbIdx++;
          }

          if (state.copyLength > state.metaBlockLength) {
            throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
          }
          state.j = 0;
          state.runningState = COPY_LOOP;
          // fall through
        case COPY_LOOP:
          int src = (state.pos - state.distance) & ringBufferMask;
          int dst = state.pos;
          int copyLength = state.copyLength - state.j;
          if ((src + copyLength < ringBufferMask) && (dst + copyLength < ringBufferMask)) {
            for (int k = 0; k < copyLength; ++k) {
              ringBuffer[dst++] = ringBuffer[src++];
            }
            state.j += copyLength;
            state.metaBlockLength -= copyLength;
            state.pos += copyLength;
          } else {
            for (; state.j < state.copyLength;) {
              ringBuffer[state.pos] =
                  ringBuffer[(state.pos - state.distance) & ringBufferMask];
              state.metaBlockLength--;
              state.j++;
              if (state.pos++ == ringBufferMask) {
                state.nextRunningState = COPY_LOOP;
                state.bytesToWrite = state.ringBufferSize;
                state.bytesWritten = 0;
                state.runningState = WRITE;
                break;
              }
            }
          }
          if (state.runningState == COPY_LOOP) {
            state.runningState = MAIN_LOOP;
          }
          continue;

        case TRANSFORM:
          if (state.copyLength >= Dictionary.MIN_WORD_LENGTH
              && state.copyLength <= Dictionary.MAX_WORD_LENGTH) {
            int offset = Dictionary.OFFSETS_BY_LENGTH[state.copyLength];
            int wordId = state.distance - state.maxDistance - 1;
            int shift = Dictionary.SIZE_BITS_BY_LENGTH[state.copyLength];
            int mask = (1 << shift) - 1;
            int wordIdx = wordId & mask;
            int transformIdx = wordId >>> shift;
            offset += wordIdx * state.copyLength;
            if (transformIdx < Transform.TRANSFORMS.length) {
              int len = Transform.transformDictionaryWord(ringBuffer, state.copyDst,
                  Dictionary.getData(), offset, state.copyLength,
                  Transform.TRANSFORMS[transformIdx]);
              state.copyDst += len;
              state.pos += len;
              state.metaBlockLength -= len;
              if (state.copyDst >= state.ringBufferSize) {
                state.nextRunningState = COPY_WRAP_BUFFER;
                state.bytesToWrite = state.ringBufferSize;
                state.bytesWritten = 0;
                state.runningState = WRITE;
                continue;
              }
            } else {
              throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
            }
          } else {
            throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE
          }
          state.runningState = MAIN_LOOP;
          continue;

        case COPY_WRAP_BUFFER:
          System.arraycopy(ringBuffer, state.ringBufferSize, ringBuffer, 0,
              state.copyDst - state.ringBufferSize);
          state.runningState = MAIN_LOOP;
          continue;

        case READ_METADATA:
          while (state.metaBlockLength > 0) {
            BitReader.readMoreInput(br);
            // Optimize
            BitReader.readBits(br, 8);
            state.metaBlockLength--;
          }
          state.runningState = BLOCK_START;
          continue;


        case COPY_UNCOMPRESSED:
          copyUncompressedData(state);
          continue;

        case WRITE:
          if (!writeRingBuffer(state)) {
            // Output buffer is full.
            return;
          }
          if (state.pos >= state.maxBackwardDistance) {
            state.maxDistance = state.maxBackwardDistance;
          }
          state.pos &= ringBufferMask;
          state.runningState = state.nextRunningState;
          continue;

        default:
          throw new BrotliRuntimeException("Unexpected state " + state.runningState);
      }
    }
    if (state.runningState == FINISHED) {
      if (state.metaBlockLength < 0) {
        throw new BrotliRuntimeException("Invalid metablock length");
      }
      BitReader.jumpToByteBoundary(br);
      BitReader.checkHealth(state.br, true);
    }
  }
}
