package com.yahoo.sketches.pig.frequencies;

import java.util.Iterator;

import org.apache.pig.EvalFunc;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.DataType;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.impl.logicalLayer.schema.Schema;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.yahoo.sketches.frequencies.ArrayOfStringsSerDe;
import com.yahoo.sketches.frequencies.FrequentItemsSketch;
import com.yahoo.sketches.pig.tuple.PigUtil;

public class FrequentStringsSketchToEstimatesTest {
  @Test
  public void nullInput() throws Exception {
    EvalFunc<DataBag> func = new FrequentStringsSketchToEstimates();
    DataBag bag = func.exec(null);
    Assert.assertNull(bag);
  }

  @Test
  public void emptyInput() throws Exception {
    EvalFunc<DataBag> func = new FrequentStringsSketchToEstimates();
    DataBag bag = func.exec(TupleFactory.getInstance().newTuple());
    Assert.assertNull(bag);
  }

  @Test
  public void emptySketch() throws Exception {
    EvalFunc<DataBag> func = new FrequentStringsSketchToEstimates();
    FrequentItemsSketch<String> sketch = new FrequentItemsSketch<String>(8);
    Tuple inputTuple = PigUtil.objectsToTuple(new DataByteArray(sketch.serializeToByteArray(new ArrayOfStringsSerDe())));
    DataBag bag = func.exec(inputTuple);
    Assert.assertNotNull(bag);
    Assert.assertEquals(bag.size(), 0);
  }

  @Test
  public void normalCase() throws Exception {
    EvalFunc<DataBag> func = new FrequentStringsSketchToEstimates();
    FrequentItemsSketch<String> sketch = new FrequentItemsSketch<String>(8);
    sketch.update("a");
    sketch.update("a");
    sketch.update("b");
    Tuple inputTuple = PigUtil.objectsToTuple(new DataByteArray(sketch.serializeToByteArray(new ArrayOfStringsSerDe())));
    DataBag bag = func.exec(inputTuple);
    Assert.assertNotNull(bag);
    Assert.assertEquals(bag.size(), 2);

    Iterator<Tuple> it = bag.iterator();
    Tuple tuple1 = it.next();
    Assert.assertEquals(tuple1.size(), 4);
    Assert.assertEquals((String)tuple1.get(0), "a");
    Assert.assertEquals((long)tuple1.get(1), 2L);
    Assert.assertEquals((long)tuple1.get(2), 2L);
    Assert.assertEquals((long)tuple1.get(3), 2L);

    Tuple tuple2 = it.next();
    Assert.assertEquals(tuple2.size(), 4);
    Assert.assertEquals((String)tuple2.get(0), "b");
    Assert.assertEquals((long)tuple2.get(1), 1L);
    Assert.assertEquals((long)tuple2.get(2), 1L);
    Assert.assertEquals((long)tuple2.get(3), 1L);
  }

  @Test
  public void schema() throws Exception {
    EvalFunc<DataBag> func = new FrequentStringsSketchToEstimates();
    Schema schema = func.outputSchema(null);
    Assert.assertNotNull(schema);
    Assert.assertEquals(schema.size(), 1);
    Assert.assertEquals(schema.getField(0).type, DataType.BAG);
    Assert.assertEquals(schema.getField(0).schema.size(), 1);
    Assert.assertEquals(schema.getField(0).schema.getField(0).type, DataType.TUPLE);
    Assert.assertEquals(schema.getField(0).schema.getField(0).schema.size(), 4);
    Assert.assertEquals(schema.getField(0).schema.getField(0).schema.getField(0).type, DataType.CHARARRAY);
    Assert.assertEquals(schema.getField(0).schema.getField(0).schema.getField(1).type, DataType.LONG);
    Assert.assertEquals(schema.getField(0).schema.getField(0).schema.getField(2).type, DataType.LONG);
    Assert.assertEquals(schema.getField(0).schema.getField(0).schema.getField(3).type, DataType.LONG);
  }
}

@@ -1503,18 +1503,13 @@
 oid 
-normalCase
+exact
 () t
@@ -2570,32 +2570,1035 @@
 t(3), 1L);%0A  %7D%0A%0A
+  @Test%0A  public void estimation() throws Exception %7B%0A    FrequentItemsSketch%3CString%3E sketch = new FrequentItemsSketch%3CString%3E(8);%0A    sketch.update(%221%22, 1000);%0A    sketch.update(%222%22, 500);%0A    sketch.update(%223%22, 200);%0A    sketch.update(%224%22, 100);%0A    sketch.update(%225%22, 50);%0A    sketch.update(%226%22, 20);%0A    sketch.update(%227%22, 10);%0A    sketch.update(%228%22, 5);%0A    sketch.update(%229%22, 2);%0A    sketch.update(%2210%22);%0A    Tuple inputTuple = PigUtil.objectsToTuple(new DataByteArray(sketch.serializeToByteArray(new ArrayOfStringsSerDe())));%0A%0A    EvalFunc%3CDataBag%3E func1 = new FrequentStringsSketchToEstimates(%22NO_FALSE_POSITIVES%22);%0A    DataBag bag1 = func1.exec(inputTuple);%0A    Assert.assertNotNull(bag1);%0A    Assert.assertTrue(bag1.size() %3C 10);%0A%0A    EvalFunc%3CDataBag%3E func2 = new FrequentStringsSketchToEstimates(%22NO_FALSE_NEGATIVES%22);%0A    DataBag bag2 = func2.exec(inputTuple);%0A    Assert.assertNotNull(bag2);%0A    Assert.assertTrue(bag2.size() %3C 10);%0A%0A    Assert.assertTrue(bag1.size() %3C bag2.size());%0A  %7D%0A%0A
   @Test%0A  public

test with specific error types