package org.cbioportal.web.parameter;

import java.util.Map;

import org.cbioportal.model.CNA;
import org.cbioportal.model.MutationEventType;
import org.cbioportal.model.util.Select;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class AlterationEventTypeFilter {

    private Map<MutationEventType, Boolean> mutationEventTypes;
    private Map<CNA, Boolean> copyNumberAlterationEventTypes;

    public Map<MutationEventType, Boolean> getMutationEventTypes() {
        return mutationEventTypes;
    }

    public void setMutationEventTypes(Map<MutationEventType, Boolean> mutationEventTypes) {
        this.mutationEventTypes = mutationEventTypes;
    }

    public Map<CNA, Boolean> getCopyNumberAlterationEventTypes() {
        return copyNumberAlterationEventTypes;
    }

    public void setCopyNumberAlterationEventTypes(Map<CNA, Boolean> copyNumberAlterationEventTypes) {
        this.copyNumberAlterationEventTypes = copyNumberAlterationEventTypes;
    }

    @JsonIgnore
    public Select<MutationEventType> getMutationTypeSelect() {
        if (mutationEventTypes == null || allOptionsSelected(mutationEventTypes)
                || mutationEventTypes.getOrDefault(MutationEventType.any, false)) {
            return Select.all();
        }

        // if MutationEventType.other is true and not allOptionsSelected
        if (mutationEventTypes.getOrDefault(MutationEventType.other, false)) {
            Select<MutationEventType> select = Select
                    .byValues(mutationEventTypes.entrySet().stream().filter(e -> !e.getValue()).map(e -> e.getKey()));
            // setting this would execute NOT IN clause in sql query
            select.inverse(true);
            return select;
        } else {
            Select<MutationEventType> select = Select
                    .byValues(mutationEventTypes.entrySet().stream().filter(e -> e.getValue()).map(e -> e.getKey()));
            return select;

        }
    }

    @JsonIgnore
    public Select<CNA> getCNAEventTypeSelect() {
        if(allOptionsSelected(copyNumberAlterationEventTypes)) {
            return Select.all();
        }
        return Select.byValues(copyNumberAlterationEventTypes.entrySet().stream().filter(e -> e.getValue())
                .map(e -> e.getKey()));
    }

    @JsonIgnore
    private boolean allOptionsSelected(Map<?, Boolean> options) {
        return options.entrySet().stream().allMatch(e -> e.getValue());
    }

}

@@ -49,19 +49,95 @@
 va.util.
-Map
+Arrays;%0Aimport java.util.List;%0Aimport java.util.Map;%0Aimport java.util.Map.Entry
 ;%0A%0Aimpor
@@ -1171,66 +1171,8 @@
 l %7C%7C
- allOptionsSelected(mutationEventTypes)%0A                %7C%7C
  mut
@@ -1221,32 +1221,139 @@
 Type.any, false)
+%0A                %7C%7C allOptionsSelected(mutationEventTypes, Arrays.asList(MutationEventType.any.toString()))
 ) %7B%0A            
@@ -1686,39 +1686,37 @@
 alue()).map(
-e -%3E e.
+Entry::
 getKey
-()
 ));%0A        
@@ -1984,31 +1984,31 @@
 .filter(
-e -%3E e.
+Entry::
 getValue
 ()).map(
@@ -2003,31 +2003,27 @@
 alue
-()
 ).map(
-e -%3E e.
+Entry::
 getKey
-()
 ));%0A
@@ -2142,16 +2142,17 @@
       if
+ 
 (allOpti
@@ -2193,16 +2193,22 @@
 entTypes
+, null
 )) %7B%0A   
@@ -2278,16 +2278,33 @@
 yValues(
+%0A                
 copyNumb
@@ -2353,31 +2353,31 @@
 .filter(
-e -%3E e.
+Entry::
 getValue
 ())%0A    
@@ -2372,48 +2372,27 @@
 alue
-())%0A                .map(e -%3E e.
+).map(Entry::
 getKey
-()
 ));%0A
@@ -2476,16 +2476,42 @@
  options
+, List%3CString%3E excludeKeys
 ) %7B%0A    
@@ -2563,28 +2563,137 @@
 ch(e -%3E 
-e.getValue()
+%7B%0A            return excludeKeys == null %7C%7C !excludeKeys.contains(e.getKey().toString()) ? e.getValue() : true;%0A        %7D
 );%0A    %7D

Exclude MutationEventType.any from allOptionsSelected