/* 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.UNINITIALIZED;

import java.io.IOException;
import java.io.InputStream;

final class State {
  int runningState = UNINITIALIZED;
  int nextRunningState;
  final BitReader br = new BitReader();
  byte[] ringBuffer;
  final int[] blockTypeTrees = new int[3 * Huffman.HUFFMAN_MAX_TABLE_SIZE];
  final int[] blockLenTrees = new int[3 * Huffman.HUFFMAN_MAX_TABLE_SIZE];

  // Current meta-block header information.
  int metaBlockLength;
  boolean inputEnd;
  boolean isUncompressed;
  boolean isMetadata;

  final HuffmanTreeGroup hGroup0 = new HuffmanTreeGroup();
  final HuffmanTreeGroup hGroup1 = new HuffmanTreeGroup();
  final HuffmanTreeGroup hGroup2 = new HuffmanTreeGroup();
  final int[] blockLength = new int[3];
  final int[] numBlockTypes = new int[3];
  final int[] blockTypeRb = new int[6];
  final int[] distRb = {16, 15, 11, 4};
  int pos = 0;
  int maxDistance = 0;
  int distRbIdx = 0;
  boolean trivialLiteralContext = false;
  int literalTreeIndex = 0;
  int literalTree;
  int j;
  int insertLength;
  byte[] contextModes;
  byte[] contextMap;
  int contextMapSlice;
  int distContextMapSlice;
  int contextLookupOffset1;
  int contextLookupOffset2;
  int treeCommandOffset;
  int distanceCode;
  byte[] distContextMap;
  int numDirectDistanceCodes;
  int distancePostfixMask;
  int distancePostfixBits;
  int distance;
  int copyLength;
  int copyDst;
  int maxBackwardDistance;
  int maxRingBufferSize;
  int ringBufferSize = 0;
  long expectedTotalSize = 0;
  byte[] customDictionary = new byte[0];
  int bytesToIgnore = 0;

  int outputOffset;
  int outputLength;
  int outputUsed;
  int bytesWritten;
  int bytesToWrite;
  byte[] output;

  // TODO: Update to current spec.
  private static int decodeWindowBits(BitReader br) {
    if (BitReader.readBits(br, 1) == 0) {
      return 16;
    }
    int n = BitReader.readBits(br, 3);
    if (n != 0) {
      return 17 + n;
    }
    n = BitReader.readBits(br, 3);
    if (n != 0) {
      return 8 + n;
    }
    return 17;
  }

  /**
   * Associate input with decoder state.
   *
   * @param state uninitialized state without associated input
   * @param input compressed data source
   */
  static void setInput(State state, InputStream input) {
    if (state.runningState != UNINITIALIZED) {
      throw new IllegalStateException("State MUST be uninitialized");
    }
    BitReader.init(state.br, input);
    int windowBits = decodeWindowBits(state.br);
    if (windowBits == 9) { /* Reserved case for future expansion. */
      throw new BrotliRuntimeException("Invalid 'windowBits' code");
    }
    state.maxRingBufferSize = 1 << windowBits;
    state.maxBackwardDistance = state.maxRingBufferSize - 16;
    state.runningState = BLOCK_START;
  }

  static void close(State state) throws IOException {
    if (state.runningState == UNINITIALIZED) {
      throw new IllegalStateException("State MUST be initialized");
    }
    if (state.runningState == CLOSED) {
      return;
    }
    state.runningState = CLOSED;
    BitReader.close(state.br);
  }
}
