package edu.washington.escience.myria.expression;

import edu.washington.escience.myria.Type;
import edu.washington.escience.myria.expression.evaluate.ExpressionOperatorParameter;

/**
 * Returns all bits in an input of BLOB_TYPE as a sequence of BOOLEAN_TYPE
 * (enumerating the input bytes in little-endian order).
 */
public class BitsetExpression extends UnaryExpression {
  /***/
  private static final long serialVersionUID = 1L;

  /**
   * This is not really unused, it's used automagically by Jackson deserialization.
   */
  @SuppressWarnings("unused")
  private BitsetExpression() {
    super();
  }

  /**
   * Takes an input of BLOB_TYPE.
   *
   * @param operand the input blob
   */
  public BitsetExpression(final ExpressionOperator operand) {
    super(operand);
  }

  @Override
  public Type getOutputType(final ExpressionOperatorParameter parameters) {
    checkOperandType(Type.BLOB_TYPE, parameters);
    return Type.BOOLEAN_TYPE;
  }

  @Override
  public String getJavaString(final ExpressionOperatorParameter parameters) {
    return new StringBuilder()
        .append("import java.util.BitSet;\n")
        .append("BitSet bs = BitSet.valueOf((")
        .append(getOperand().getJavaString(parameters))
        .append("));\n")
        .append("boolean[] vals = new boolean[bs.size()];\n")
        .append("for (int i = 0; i < bs.size(); ++i) {\n")
        .append("vals[i] = bs.get(i);\n")
        .append("}\n")
        .append("return vals;\n")
        .toString();
  }

  @Override
  public String getJavaExpressionWithAppend(final ExpressionOperatorParameter parameters) {
    return new StringBuilder()
        .append("import java.util.BitSet;\n")
        .append("BitSet bs = BitSet.valueOf((")
        .append(getOperand().getJavaString(parameters))
        .append("));")
        .append(Expression.COUNT)
        .append(".appendInt(bs.size());\n")
        .append("for (int i = 0; i < bs.size(); ++i) {\n")
        .append(Expression.RESULT)
        .append(".appendBoolean(bs.get(i));\n")
        .append("}\n")
        .toString();
  }

  @Override
  public boolean hasArrayOutputType() {
    return true;
  }
}

@@ -1089,39 +1089,110 @@
 append(%22
-import java.util.BitSet
+ByteBuffer bb = (%22)%0A        .append(getOperand().getJavaString(parameters))%0A        .append(%22)
 ;%5Cn%22)%0A  
@@ -1198,32 +1198,42 @@
        .append(%22
+java.util.
 BitSet bs = BitS
@@ -1220,32 +1220,42 @@
 til.BitSet bs = 
+java.util.
 BitSet.valueOf((
@@ -1245,33 +1245,38 @@
 .BitSet.valueOf(
-(
+bb);%5Cn
 %22)%0A        .appe
@@ -1282,67 +1282,41 @@
 end(
-getOperand().getJavaString(parameters))%0A        .append(%22))
+%22int bits_len = bb.capacity() * 8
 ;%5Cn%22
@@ -1364,24 +1364,23 @@
 oolean%5Bb
-s.size()
+its_len
 %5D;%5Cn%22)%0A 
@@ -1412,32 +1412,31 @@
 i = 0; i %3C b
-s.size()
+its_len
 ; ++i) %7B%5Cn%22)
@@ -1717,31 +1717,102 @@
 nd(%22
-import java.util.BitSet
+ByteBuffer bb = (%22)%0A        .append(getOperand().getJavaString(parameters))%0A        .append(%22)
 ;%5Cn%22
@@ -1830,16 +1830,26 @@
 append(%22
+java.util.
 BitSet b
@@ -1852,16 +1852,26 @@
 et bs = 
+java.util.
 BitSet.v
@@ -1877,17 +1877,22 @@
 valueOf(
-(
+bb);%5Cn
 %22)%0A     
@@ -1906,68 +1906,44 @@
 end(
-getOperand().getJavaString(parameters))%0A        .append(%22));
+%22int bits_len = bb.capacity() * 8;%5Cn
 %22)%0A 
@@ -2004,24 +2004,23 @@
 endInt(b
-s.size()
+its_len
 );%5Cn%22)%0A 
@@ -2060,16 +2060,15 @@
  %3C b
-s.size()
+its_len
 ; ++

fix bitset size