package aperf.api.filter;

import aperf.api.exceptions.FilterException;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Makes multiple filters act as one. All or nothing.
 */
@Filter(name = "Multi", desc = "Makes multiple filters act as one. All or nothing.", valueDesc = "Array of more filters")
public class MultiFilter implements IFilter {
    private List<IFilter> filters;

    @Override
    public boolean hits(Object o) {
        for (IFilter filter : filters) {
            if (!filter.hits(o))
                return false;
        }

        return true;
    }

    @Override
    public void load(JsonElement json) throws FilterException.FilterLoadException {
        if (json.isJsonArray()) {
            filters = new ArrayList<IFilter>();
            JsonArray jsonArray = json.getAsJsonArray();
            for (JsonElement element : jsonArray) {
                if (!element.isJsonObject()) continue;
                try {
                    filters.add(JsonFilterMarshaler.unmarshal(element.getAsJsonObject()));
                } catch (FilterException.FilterCreationException e) {
                    throw new FilterException.FilterLoadException(this, "Sub-filter failed to create", e);
                } catch (FilterException.FilterNotFoundException e) {
                    throw new FilterException.FilterLoadException(this, "Sub-filter failed to load", e);
                }
            }
        }
    }

    @Override
    public void load(String str) throws FilterException.FilterLoadException {
        // Not Supported!
    }

    @Override
    public JsonElement save() throws FilterException.FilterSaveException {
        JsonArray ret = new JsonArray();
        for (IFilter filter : filters) {
            JsonObject subFilter;
            try {
                subFilter = JsonFilterMarshaler.marshal(filter);
            } catch (FilterException.FilterSaveException e) {
                throw new FilterException.FilterSaveException(this, "Sub-filter failed to save", e);
            }
            if (subFilter == null) continue;
            ret.add(subFilter);
        }
        return ret;
    }

    public void addFilter(IFilter filter) {
        filters.add(filter);
    }

    public void removeFilter(IFilter filter) {
        if (!filters.remove(filter)) {
            for (IFilter subF : filters) {
                if (subF instanceof MultiFilter) {
                    ((MultiFilter) subF).removeFilter(filter);
                }
            }
        }
    }
}

@@ -20,16 +20,50 @@
 ilter;%0A%0A
+import aperf.api.FilterRegistrar;%0A
 import a
@@ -1678,25 +1678,711 @@
     
-// Not Supported!
+String%5B%5D filterParts = str.split(%22,%22);%0A        for (String filter : filterParts) %7B%0A            String filterName = filter.substring(0, filter.indexOf(':'));%0A            String filterConfig = filter.substring(filter.indexOf(':') + 1);%0A            try %7B%0A                filters.add(FilterRegistrar.INSTANCE.loadFilter(filterName, filterConfig));%0A            %7D catch (FilterException.FilterCreationException e) %7B%0A                throw new FilterException.FilterLoadException(this, %22Sub-filter failed to create%22, e);%0A            %7D catch (FilterException.FilterNotFoundException e) %7B%0A                throw new FilterException.FilterLoadException(this, %22Sub-filter failed to load%22, e);%0A            %7D%0A        %7D
 %0A   

Allow string configuration of MultiFilter. Each sub-filter is split by a comma (,) and written as name:config where name is the name of the sub-filter to load. Config CAN have colons (:), so long as the name is before the FIRST colon