package com.gentics.mesh.graphql.filter;

import com.gentics.mesh.core.data.GraphFieldContainer;
import com.gentics.mesh.core.rest.common.FieldTypes;
import com.gentics.mesh.core.rest.schema.FieldSchema;
import com.gentics.mesh.core.rest.schema.SchemaModel;
import com.gentics.mesh.graphql.context.GraphQLContext;
import com.gentics.mesh.graphqlfilter.filter.FilterField;
import com.gentics.mesh.graphqlfilter.filter.MainFilter;
import com.gentics.mesh.graphqlfilter.filter.MappedFilter;
import com.gentics.mesh.graphqlfilter.filter.StringFilter;

import java.util.List;
import java.util.stream.Collectors;

public class FieldFilter extends MainFilter<GraphFieldContainer> {
    private static final String NAME_PREFIX = "FieldFilter.";

    public static FieldFilter filter(GraphQLContext context, SchemaModel container) {
        return context.getOrStore(NAME_PREFIX + container.getName(), () -> new FieldFilter(container));
    }

    private final SchemaModel schema;

    private FieldFilter(SchemaModel container) {
        super(container.getName() + "FieldFilter", "Filters by fields");
        this.schema = container;
    }

    @Override
    protected List<FilterField<GraphFieldContainer, ?>> getFilters() {
        return schema.getFields().stream()
            .map(this::createFieldFilter)
            .collect(Collectors.toList());
    }

    private FilterField<GraphFieldContainer, ?> createFieldFilter(FieldSchema fieldSchema) {
        String schemaName = schema.getName();
        String name = fieldSchema.getName();
        String description = "Filters by the field " + name;
        FieldTypes type = FieldTypes.valueByName(fieldSchema.getType());
        switch (type) {
            case STRING:
                return new FieldMappedFilter<>(name, description, StringFilter.filter(), node -> node.getString(name).getString(), schemaName);
            case HTML:
                return new FieldMappedFilter<>(name, description, StringFilter.filter(), node -> node.getHtml(name).getHTML(), schemaName);
            case DATE:
            case NUMBER:
            case BOOLEAN:
            case BINARY:
            case LIST:
            case NODE:
            case MICRONODE:
                // TODO correctly implement other types
                return new FieldMappedFilter<>(name, description, StringFilter.filter(), node -> "bogus", schemaName);
            default:
                throw new RuntimeException("Unexpected type " + type);
        }
    }
}

@@ -307,16 +307,133 @@
 ontext;%0A
+import com.gentics.mesh.graphqlfilter.filter.BooleanFilter;%0Aimport com.gentics.mesh.graphqlfilter.filter.DateFilter;%0A
 import c
@@ -543,67 +543,8 @@
 er;%0A
-import com.gentics.mesh.graphqlfilter.filter.MappedFilter;%0A
 impo
@@ -2120,20 +2120,133 @@
     
-case NUMBER:
+    return new FieldMappedFilter%3C%3E(name, description, DateFilter.filter(), node -%3E node.getDate(name).getDate(), schemaName);
 %0A   
@@ -2284,43 +2284,207 @@
     
+  
-case BINARY:%0A            case LIST:
+  return new FieldMappedFilter%3C%3E(name, description, BooleanFilter.filter(), node -%3E node.getBoolean(name).getBoolean(), schemaName);%0A            // TODO correctly implement other types OR HIDE THEM
 %0A   
@@ -2498,19 +2498,21 @@
   case N
-ODE
+UMBER
 :%0A      
@@ -2526,17 +2526,14 @@
 ase 
-MICRONODE
+BINARY
 :%0A  
@@ -2546,51 +2546,69 @@
     
-    // TODO correctly implement other types
+case LIST:%0A            case NODE:%0A            case MICRONODE:
 %0A   

Add date and boolean field filter