package com.github.bohnman.squiggly;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.github.bohnman.squiggly.context.provider.SimpleSquigglyContextProvider;
import com.github.bohnman.squiggly.context.provider.SquigglyContextProvider;
import com.github.bohnman.squiggly.filter.SquigglyPropertyFilter;
import com.github.bohnman.squiggly.filter.SquigglyPropertyFilterMixin;
import com.github.bohnman.squiggly.parser.SquigglyParser;

/**
 * Provides various way of registering a {@link SquigglyPropertyFilter} with a Jackson ObjectMapper.
 */
public class Squiggly {

    private Squiggly() {
    }

    /**
     * Initialize a @{@link SquigglyPropertyFilter} with a static filter expression.
     *
     * @param mapper the Jackson Object Mapper
     * @param filter the filter expressions
     * @return object mapper, mainly for convenience
     * @throws IllegalStateException if the filter was unable to be registered
     */
    public static ObjectMapper init(ObjectMapper mapper, String filter) throws IllegalStateException {
        return init(mapper, new SimpleSquigglyContextProvider(new SquigglyParser(), filter));
    }

    /**
     * Initialize a @{@link SquigglyPropertyFilter} with a specific context provider.
     *
     * @param mapper          the Jackson Object Mapper
     * @param contextProvider the context provider to use
     * @return object mapper, mainly for convenience
     * @throws IllegalStateException if the filter was unable to be registered
     */
    public static ObjectMapper init(ObjectMapper mapper, SquigglyContextProvider contextProvider) throws IllegalStateException {
        return init(mapper, new SquigglyPropertyFilter(contextProvider));
    }

    /**
     * Initialize a @{@link SquigglyPropertyFilter} with a specific property filter.
     *
     * @param mapper the Jackson Object Mapper
     * @param filter the proeprty filter
     * @return object mapper, mainly for convenience
     * @throws IllegalStateException if the filter was unable to be registered
     */
    @SuppressWarnings("deprecation")
    public static ObjectMapper init(ObjectMapper mapper, SquigglyPropertyFilter filter) throws IllegalStateException {
        FilterProvider filterProvider = mapper.getSerializationConfig().getFilterProvider();
        SimpleFilterProvider simpleFilterProvider;

        if (filterProvider instanceof SimpleFilterProvider) {
            simpleFilterProvider = (SimpleFilterProvider) filterProvider;
        } else if (filterProvider == null) {
            simpleFilterProvider = new SimpleFilterProvider();
            mapper.setFilters(simpleFilterProvider);
        } else {
            throw new IllegalStateException("Unable to register squiggly filter with FilterProvider of type " + filterProvider.getClass().getName() + ".  You'll have to register the filter manually");

        }

        simpleFilterProvider.addFilter(SquigglyPropertyFilter.FILTER_ID, filter);
        mapper.addMixIn(Object.class, SquigglyPropertyFilterMixin.class);

        return mapper;
    }

}

@@ -1339,450 +1339,1429 @@
  a s
-pecific context provider.%0A     *%0A     * @param mapper          the Jackson Object Mapper%0A     * @param contextProvider the context provider to use%0A     * @return object mapper, mainly for convenience%0A     * @throws IllegalStateException if the filter was unable to be registered%0A     */%0A    public static ObjectMapper init(ObjectMapper mapper, SquigglyContextProvider contextProvider) throws IllegalStateException %7B%0A        return init(mapper
+tatic filter expression.%0A     *%0A     * @param mappers the Jackson Object Mappers to init%0A     * @param filter the filter expressions%0A     * @throws IllegalStateException if the filter was unable to be registered%0A     */%0A    public static void init(Iterable%3CObjectMapper%3E mappers, String filter) throws IllegalStateException %7B%0A        init(mappers, new SimpleSquigglyContextProvider(new SquigglyParser(), filter));%0A    %7D%0A%0A    /**%0A     * Initialize a @%7B@link SquigglyPropertyFilter%7D with a specific context provider.%0A     *%0A     * @param mapper          the Jackson Object Mapper%0A     * @param contextProvider the context provider to use%0A     * @return object mapper, mainly for convenience%0A     * @throws IllegalStateException if the filter was unable to be registered%0A     */%0A    public static ObjectMapper init(ObjectMapper mapper, SquigglyContextProvider contextProvider) throws IllegalStateException %7B%0A        return init(mapper, new SquigglyPropertyFilter(contextProvider));%0A    %7D%0A%0A    /**%0A     * Initialize a @%7B@link SquigglyPropertyFilter%7D with a specific context provider.%0A     *%0A     * @param mappers          the Jackson Object Mappers to init%0A     * @param contextProvider the context provider to use%0A     * @throws IllegalStateException if the filter was unable to be registered%0A     */%0A    public static void init(Iterable%3CObjectMapper%3E mappers, SquigglyContextProvider contextProvider) %7B%0A        init(mappers
 , ne
@@ -2986,18 +2986,18 @@
  the pro
-e
 p
+e
 rty filt
@@ -4154,10 +4154,485 @@
 %0A    %7D%0A%0A
+    /**%0A     * Initialize a @%7B@link SquigglyPropertyFilter%7D with a specific property filter.%0A     *%0A     * @param mappers the Jackson Object Mappers to init%0A     * @param filter the property filter%0A     * @throws IllegalStateException if the filter was unable to be registered%0A     */%0A    public static void init(Iterable%3CObjectMapper%3E mappers, SquigglyPropertyFilter filter) %7B%0A        for (ObjectMapper mapper : mappers) %7B%0A            init(mapper, filter);%0A        %7D%0A    %7D%0A%0A
 %7D%0A

allow initializing multiple object mappers at once