package io.sigpipe.sing.query;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import io.sigpipe.sing.dataset.feature.FeatureType;
import io.sigpipe.sing.graph.DataContainer;
import io.sigpipe.sing.graph.Vertex;
import io.sigpipe.sing.serialization.SerializationException;
import io.sigpipe.sing.serialization.SerializationInputStream;
import io.sigpipe.sing.serialization.SerializationOutputStream;

public class MetaQuery extends Query {


    public MetaQuery() {

    }

    }

    public void execute(Vertex root, SerializationOutputStream out)
    throws IOException, QueryException {
        this.query(root, out);
    }

    private void query(Vertex vertex, SerializationOutputStream out)
    throws IOException, QueryException {
        DataContainer container = vertex.getData();
        if (container != null) {
            //System.out.println("Serializing: " + vertex.toString());
            container.serialize(out);
        }

        List<Expression> expList = expressions.get(vertex.getLabel().getName());
        if (expList != null) {
            Set<Vertex> matches = evaluate(vertex, expList);
            for (Vertex match : matches) {
                if (match == null) {
                    continue;
                }

                if (match.getLabel().getType() == FeatureType.NULL) {
                    continue;
                }

                query(match, out);
            }
        } else {
            /* No expression operates on this vertex. Consider all children. */
            for (Vertex neighbor : vertex.getAllNeighbors()) {
                query(neighbor, out);
            }
        }
    }

    @Deserialize
    public MetaQuery(SerializationInputStream in)
    throws IOException, SerializationException {
        int size = in.readInt();
        this.expressions = new HashMap<>(size);
        for (int i = 0; i < size; ++i) {
            int listSize = in.readInt();
            List<Expression> expList = new ArrayList<>(listSize);
            for (int j = 0; j < listSize; ++j) {
                Expression exp = new Expression(in);
                expList.add(exp);
            }
            String featureName = expList.get(0).getOperand().getName();
            this.expressions.put(featureName, expList);
        }
    }

    @Override
    public void serialize(SerializationOutputStream out)
    throws IOException {
        out.writeInt(this.expressions.size());
        for (List<Expression> expList : this.expressions.values()) {
            out.writeInt(expList.size());
            for (Expression expression : expList) {
                expression.serialize(out);
            }
        }
    }

}


@@ -552,24 +552,38 @@
   %7D%0A%0A    %7D%0A%0A
+    @Override%0A
     public v
@@ -609,39 +609,8 @@
 root
-, SerializationOutputStream out
 )%0A  
@@ -671,21 +671,16 @@
 ery(root
-, out
 );%0A    %7D
@@ -721,39 +721,8 @@
 rtex
-, SerializationOutputStream out
 )%0A  
@@ -920,46 +920,8 @@
 ));%0A
-            container.serialize(out);%0A
     
@@ -1375,21 +1375,16 @@
 ry(match
-, out
 );%0A     
@@ -1586,13 +1586,8 @@
 hbor
-, out
 );%0A 

Update for base class changes