// Path: java/core/src/main/java/eu/mais_h/mathsync/digest/Digester.java
// public interface Digester {
// 
//   /**
//    * Digests an item serialized as an array of bytes.
//    *
//    * <p>Any byte array value must be accepted and have a non <code>null</code> return value: for any <code>a</code>,
//    * <code>digest(a) != null</code>.</p>
//    *
//    * <p>All valid inputs should produce in output an array of the same size:for any <code>a1</code> and
//    * <code>a2</code>, <code>digest(a1).length == digest(a2).length</code>.</p>
//    *
//    * <p>The output must be consistent, an identical output should be returned if called twice on the same array: for
//    * any <code>a1</code> and <code>a2</code>, <code>Arrays.equals(a1, a2)</code> implies
//    * <code>Arrays.equals(digest(a1), digest(a2))</code>.</p>
//    *
//    * <p>In addition to those constrains, it is recommended that it has the properties of a
//    * <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">cryptographic hash function</a>.</p>
//    *
//    * @param source the item serialized as an array of bytes.
//    * @return the message digest of the item.
//    * @throws IllegalArgumentException if the input array is <code>null</code>.
//    */
//   byte[] digest(byte[] source);
// }
// 
// Path: java/core/src/main/java/eu/mais_h/mathsync/digest/Sha1Digester.java
// public class Sha1Digester implements Digester {
// 
//   private static final String DIGEST_ALGORITHM = "SHA-1";
//   private static final Sha1Digester INSTANCE = new Sha1Digester();
// 
//   private Sha1Digester() {
//   }
// 
//   /**
//    * Digests according to SHA-1 specification.
//    */
//   @Override
//   public byte[] digest(byte[] source) {
//     if (source == null) {
//       throw new IllegalArgumentException("Cannot digest null source");
//     }
// 
//     MessageDigest md;
//     try {
//       md = MessageDigest.getInstance(DIGEST_ALGORITHM);
//     } catch (NoSuchAlgorithmException e) {
//       throw new AssertionError("JVM does not support " + DIGEST_ALGORITHM + " algorithm", e);
//     }
//     md.update(source);
//     return md.digest();
//   }
// 
//   @Override
//   public String toString() {
//     return DIGEST_ALGORITHM;
//   }
// 
//   /**
//    * Retrieves an instance of this digester kind.
//    *
//    * @return an instance of this digester kind.
//    */
//   public static Sha1Digester get() {
//     return INSTANCE;
//   }
// }
// 
// Path: java/core/src/main/java/eu/mais_h/mathsync/util/Function.java
// public interface Function<T, R> {
// 
//   /**
//    * Applies this function to the given argument.
//    * 
//    * @param t the function argument.
//    * @return the function result.
//    */
//   R apply(T t);
// }


import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
import java.util.Arrays;
import java.util.Set;
import org.junit.Test;
import eu.mais_h.mathsync.digest.Digester;
import eu.mais_h.mathsync.digest.Sha1Digester;
import eu.mais_h.mathsync.util.Function;
package eu.mais_h.mathsync;





public class SummarizerFromJsonTest {

  private Digester digester = Sha1Digester.get();
  private BucketSelector selector = Defaults.defaultSelector();

  private byte[] item1 = new byte[] { 1, 2 };
  private byte[] item2 = new byte[] { 2, 2 };
  private byte[] item3 = new byte[] { 3, 2 };
  
  @Test
  public void test_should_generate_summary_from_IBF() {
    final Summary ibf = new Ibf(32, digester, selector).plus(item1).plus(item2).plus(item3);
    
    Summarizer throughJson = SummarizerFromJson.custom(new Function<Integer, String>() {
      
      @Override
      public String apply(Integer t) {
        assertThat(t).isEqualTo(5);
        return ibf.toJSON();
      }
    }, digester, selector);

    Summary deserialized = throughJson.summarize(5);
    
    Difference<byte[]> diff = deserialized.toDifference();
    assertThatSetOfArrayEquals(diff.added(), item1, item2, item3);
    assertThat(diff.removed()).isEmpty();
  }
  
  @Test
  public void test_should_generate_summary_from_full_content() {
    final Summary fullContent = FullContent.EMPTY.plus(item1).plus(item2).plus(item3);
    
    Summarizer throughJson = SummarizerFromJson.custom(new Function<Integer, String>() {
      
      @Override
      public String apply(Integer t) {
        assertThat(t).isEqualTo(5);
// Path: java/core/src/main/java/eu/mais_h/mathsync/digest/Digester.java
// public interface Digester {
// 
//   /**
//    * Digests an item serialized as an array of bytes.
//    *
//    * <p>Any byte array value must be accepted and have a non <code>null</code> return value: for any <code>a</code>,
//    * <code>digest(a) != null</code>.</p>
//    *
//    * <p>All valid inputs should produce in output an array of the same size:for any <code>a1</code> and
//    * <code>a2</code>, <code>digest(a1).length == digest(a2).length</code>.</p>
//    *
//    * <p>The output must be consistent, an identical output should be returned if called twice on the same array: for
//    * any <code>a1</code> and <code>a2</code>, <code>Arrays.equals(a1, a2)</code> implies
//    * <code>Arrays.equals(digest(a1), digest(a2))</code>.</p>
//    *
//    * <p>In addition to those constrains, it is recommended that it has the properties of a
//    * <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">cryptographic hash function</a>.</p>
//    *
//    * @param source the item serialized as an array of bytes.
//    * @return the message digest of the item.
//    * @throws IllegalArgumentException if the input array is <code>null</code>.
//    */
//   byte[] digest(byte[] source);
// }
// 
// Path: java/core/src/main/java/eu/mais_h/mathsync/digest/Sha1Digester.java
// public class Sha1Digester implements Digester {
// 
//   private static final String DIGEST_ALGORITHM = "SHA-1";
//   private static final Sha1Digester INSTANCE = new Sha1Digester();
// 
//   private Sha1Digester() {
//   }
// 
//   /**
//    * Digests according to SHA-1 specification.
//    */
//   @Override
//   public byte[] digest(byte[] source) {
//     if (source == null) {
//       throw new IllegalArgumentException("Cannot digest null source");
//     }
// 
//     MessageDigest md;
//     try {
//       md = MessageDigest.getInstance(DIGEST_ALGORITHM);
//     } catch (NoSuchAlgorithmException e) {
//       throw new AssertionError("JVM does not support " + DIGEST_ALGORITHM + " algorithm", e);
//     }
//     md.update(source);
//     return md.digest();
//   }
// 
//   @Override
//   public String toString() {
//     return DIGEST_ALGORITHM;
//   }
// 
//   /**
//    * Retrieves an instance of this digester kind.
//    *
//    * @return an instance of this digester kind.
//    */
//   public static Sha1Digester get() {
//     return INSTANCE;
//   }
// }
// 
// Path: java/core/src/main/java/eu/mais_h/mathsync/util/Function.java
// public interface Function<T, R> {
// 
//   /**
//    * Applies this function to the given argument.
//    * 
//    * @param t the function argument.
//    * @return the function result.
//    */
//   R apply(T t);
// }


// Path: java/core/src/test/java/eu/mais_h/mathsync/SummarizerFromJsonTest.java
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
import java.util.Arrays;
import java.util.Set;
import org.junit.Test;
import eu.mais_h.mathsync.digest.Digester;
import eu.mais_h.mathsync.digest.Sha1Digester;
import eu.mais_h.mathsync.util.Function;

package eu.mais_h.mathsync;





public class SummarizerFromJsonTest {

  private Digester digester = Sha1Digester.get();
  private BucketSelector selector = Defaults.defaultSelector();

  private byte[] item1 = new byte[] { 1, 2 };
  private byte[] item2 = new byte[] { 2, 2 };
  private byte[] item3 = new byte[] { 3, 2 };
  
  @Test
  public void test_should_generate_summary_from_IBF() {
    final Summary ibf = new Ibf(32, digester, selector).plus(item1).plus(item2).plus(item3);
    
    Summarizer throughJson = SummarizerFromJson.custom(new Function<Integer, String>() {
      
      @Override
      public String apply(Integer t) {
        assertThat(t).isEqualTo(5);
        return ibf.toJSON();
      }
    }, digester, selector);

    Summary deserialized = throughJson.summarize(5);
    
    Difference<byte[]> diff = deserialized.toDifference();
    assertThatSetOfArrayEquals(diff.added(), item1, item2, item3);
    assertThat(diff.removed()).isEmpty();
  }
  
  @Test
  public void test_should_generate_summary_from_full_content() {
    final Summary fullContent = FullContent.EMPTY.plus(item1).plus(item2).plus(item3);
    
    Summarizer throughJson = SummarizerFromJson.custom(new Function<Integer, String>() {
      
      @Override
      public String apply(Integer t) {
        assertThat(t).isEqualTo(5);
        return fullContent.toJSON();