/*
 * Copyright 2017, Yahoo! Inc. Licensed under the terms of the
 * Apache License 2.0. See LICENSE file at the project root for terms.
 */

package com.yahoo.sketches.hll;

import static com.yahoo.sketches.hll.PreambleUtil.FAMILY_ID;
import static com.yahoo.sketches.hll.PreambleUtil.LIST_PREINTS;
import static com.yahoo.sketches.hll.PreambleUtil.SER_VER;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

import org.testng.annotations.Test;

import com.yahoo.memory.WritableMemory;
import com.yahoo.sketches.SketchesArgumentException;
import com.yahoo.sketches.SketchesStateException;

/**
 * @author Lee Rhodes
 *
 */
public class CouponListTest {

  @Test
  public void checkIterator() {
    HllSketch sk = new HllSketch(8);
    for (int i = 0; i < 15; i++) { sk.update(i); }
    PairIterator itr = sk.getIterator();
    println(itr.getHeader());
    while (itr.nextAll()) {
      int key = itr.getKey();
      int val = itr.getValue();
      int idx = itr.getIndex();
      println("Idx: " + idx + ", Key: " + key + ", Val: " + val);
    }
  }

  @Test(expectedExceptions = SketchesStateException.class)
  public void checkPutHipAccum() {
    HllSketch sk = new HllSketch(8);
    for (int i = 0; i < 15; i++) { sk.update(i); }
    sk.hllSketchImpl.putHipAccum(0);
  }

  @Test
  public void checkCheckPreamble() {
    HllSketch sk = new HllSketch(8, TgtHllType.HLL_6);
    for (int i = 0; i < 7; i++) { sk.update(i); }
    byte[] byteArr = sk.toCompactByteArray();
    WritableMemory wmem = WritableMemory.wrap(byteArr);
    final long memAdd = wmem.getCumulativeOffset(0);
    CouponList.checkPreamble(wmem, byteArr, memAdd, CurMode.LIST);
    try {
      wmem.putByte(PreambleUtil.PREAMBLE_INTS_BYTE, (byte) 0);
      CouponList.checkPreamble(wmem, byteArr, memAdd, CurMode.LIST);
      fail();
    } catch (SketchesArgumentException e) {
      wmem.putByte(PreambleUtil.PREAMBLE_INTS_BYTE, (byte) LIST_PREINTS);
    }
    try {
      wmem.putByte(PreambleUtil.SER_VER_BYTE, (byte) 0);
      CouponList.checkPreamble(wmem, byteArr, memAdd, CurMode.LIST);
      fail();
    } catch (SketchesArgumentException e) {
      wmem.putByte(PreambleUtil.SER_VER_BYTE, (byte) SER_VER);
    }
    try {
      wmem.putByte(PreambleUtil.FAMILY_BYTE, (byte) 0);
      CouponList.checkPreamble(wmem, byteArr, memAdd, CurMode.LIST);
      fail();
    } catch (SketchesArgumentException e) {
      wmem.putByte(PreambleUtil.FAMILY_BYTE, (byte) FAMILY_ID);
    }
  }

  @Test
  public void checkDuplicatesAndMisc() {
    HllSketch sk = new HllSketch(8);
    for (int i = 1; i <= 7; i++) {
      sk.update(i);
      sk.update(i);
    }
    assertEquals(sk.getCurrentMode(), CurMode.LIST);
    sk.getRelErr(1);
    sk.getRelErrFactor(1);
    assertEquals(sk.getCompositeEstimate(), 7.0, 7 * .01);
    sk.update(8);
    sk.update(8);
    assertEquals(sk.getCurrentMode(), CurMode.SET);
    assertEquals(sk.getCompositeEstimate(), 8.0, 8 * .01);
    sk.getRelErr(1);
    sk.getRelErrFactor(1);
    for (int i = 9; i <= 25; i++) {
      sk.update(i);
      sk.update(i);
    }
    assertEquals(sk.getCurrentMode(), CurMode.HLL);
    assertEquals(sk.getCompositeEstimate(), 25.0, 25 * .1);
    sk.getRelErr(1);
    sk.getRelErrFactor(1);
  }

  @Test
  public void checkMisc() {

  }

  @Test
  public void printlnTest() {
    println("PRINTING: "+this.getClass().getName());
  }

  /**
   * @param s value to print
   */
  static void println(String s) {
    //System.out.println(s); //disable here
  }
}

@@ -3283,25 +3283,672 @@
 id check
-Misc() %7B%0A
+GrowHashSet() %7B%0A    int lgK = 21;%0A    HllSketch sk = new HllSketch(lgK);%0A    int u = ((1 %3C%3C (lgK - 3))/4) * 3;%0A    println(%22U: %22 + u);%0A    for (int i = 0; i %3C u; i++) %7B%0A      sk.update(i);%0A    %7D%0A    double est1 = sk.getEstimate();%0A    double re1 = (est1 / u) - 1.0;%0A    println(%22Est1: %22 + est1 + %22, u: %22 + u + %22, re1: %22 + re1);%0A    assertEquals(sk.getEstimate(), u, u * 100.0E-6);%0A    byte%5B%5D byteArray = sk.toCompactByteArray();%0A    HllSketch sk2 = HllSketch.heapify(byteArray);%0A    double est2 = sk2.getEstimate();%0A    double re2 = (est2 / est1) - 1.0;%0A    println(%22Est2: %22 + est2 + %22, Est1: %22 + est1 + %22, re2: %22 + re2);%0A    assertEquals(est2, est1, 0.0);
 %0A  %7D%0A%0A  
@@ -4120,14 +4120,12 @@
 ) %7B%0A
+
     
-//
 Syst

Test for vulnerability of bug in growHashSet.