package com.galois.qrstream.qrpipe;

import java.util.HashMap;
import java.util.Map;

/**
 * Stores message from sequence of decoded QR codes. Note, the initial
 * capacity is unknown until first QR code is read.
 */
public class DecodedMessage {
  /* Container for saving received data */
  private Map<Integer, byte[]> receivedData;

  /* Track progress of decoding */
  private final DecodeState decodeState;
  private final IProgress decodeProgress;

  private static final boolean DEBUG = false;

  public DecodedMessage (IProgress progress) {
    receivedData = null;
    decodeState = new DecodeState();
    decodeProgress = progress;
    decodeProgress.changeState(decodeState);
  }

  /**
   * Mark progress of data transmission by setting the {@code chunkId}
   * bit in {@code DecodeState} to true whenever a QR code has been decoded.
   * It also sets up the initial sizes of {@code receivedData} if this is
   * the first QR code encountered.
   */
  public void saveMessageChunk(int chunkId, int totalChunks, byte[] msg) {
    if (totalChunks < 1 || chunkId < 1) {
      throw new IllegalArgumentException("Expected positive chunk inputs.");
    }else if (msg.length < 1) {
      throw new IllegalArgumentException("Invalid message length.");
    }
    // Set up message container if this is the first QR code encountered.
    // Could have initialized before knowing capacity but then
    // it's likely map would need to be resized.
    if (receivedData == null) {
      receivedData = new HashMap<Integer, byte[]>(totalChunks);
      decodeState.setInitialCapacity(totalChunks);
      if(DEBUG) System.out.println("saveMessageChunk: initialize to size " + totalChunks);
    }
    // Save message part if we haven't seen it already.
    if (!receivedData.containsKey(chunkId)) {
      decodeState.markDataReceived(chunkId);
      receivedData.put(chunkId, msg.clone());
      decodeProgress.changeState(decodeState);
      if(DEBUG) System.out.println("saveMessageChunk: updated state to " + decodeState.getState());
    }else{
      if(DEBUG) System.out.println("saveMessageChunk: nothing to do - already recorded chunk");
    }
  }

  public void testProgressUpdate(int i) {
    int pretendCapacity = 2;
    if (i < 0 || i >= pretendCapacity) {
      throw new IllegalArgumentException("Expected positive chunk inputs.");
    }
    if (receivedData == null) {
      receivedData = new HashMap<Integer, byte[]>(pretendCapacity);
      decodeState.setInitialCapacity(pretendCapacity);
    }
    // Save message part if we haven't seen it already.
    if (!receivedData.containsKey(i)) {
      decodeState.markDataReceived(i);
      receivedData.put(i, new byte[] {(byte)0xde,(byte)0xad,(byte)0xbe,(byte)0xef});
      decodeProgress.changeState(decodeState);
    } else {
      if(DEBUG) System.out.println("Chunk " + i + " has already been saved.");
    }
  }
}

@@ -1596,32 +1596,42 @@
 %0A      if(DEBUG)
+ %7B%0A       
  System.out.prin
@@ -1686,24 +1686,32 @@
 talChunks);%0A
+      %7D%0A
     %7D%0A    //
@@ -1951,32 +1951,42 @@
 %0A      if(DEBUG)
+ %7B%0A       
  System.out.prin
@@ -2050,24 +2050,32 @@
 etState());%0A
+      %7D%0A
     %7Delse%7B%0A 
@@ -2080,32 +2080,42 @@
 %0A      if(DEBUG)
+ %7B%0A       
  System.out.prin
@@ -2175,24 +2175,32 @@
 ed chunk%22);%0A
+      %7D%0A
     %7D%0A  %7D%0A%0A 
@@ -2849,16 +2849,26 @@
 f(DEBUG)
+ %7B%0A       
  System.
@@ -2919,24 +2919,32 @@
 n saved.%22);%0A
+      %7D%0A
     %7D%0A  %7D%0A%7D%0A

resolve pmd failures