package org.onosproject.cord.gui.model;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.HashMap;
import java.util.Map;

import static org.onosproject.cord.gui.model.XosFunctionDescriptor.URL_FILTER;

/**
 * Utility factory for operating on XOS functions.
 */
public class XosFunctionFactory extends JsonFactory {

    private static final String PARAMS = "params";
    private static final String LEVEL = "level";
    private static final String LEVELS = "levels";

    private static final UrlFilterFunction.Level DEFAULT_FILTER_LEVEL =
        UrlFilterFunction.Level.PG;


    // no instantiation
    private XosFunctionFactory() {}

    /**
     * Produces the JSON representation of the given XOS function descriptor.
     *
     * @param xfd function descriptor
     * @return JSON encoding
     */
    public static ObjectNode toObjectNode(XosFunctionDescriptor xfd) {
        ObjectNode root = objectNode()
                .put(ID, xfd.id())
                .put(NAME, xfd.displayName())
                .put(DESC, xfd.description());
        root.set(PARAMS, paramsForXfd(xfd));
        return root;
    }

    private static ObjectNode paramsForXfd(XosFunctionDescriptor xfd) {
        ParamsFactory psf = PARAM_MAP.get(xfd);
        if (psf == null) {
            psf = DEF_PARAMS_FACTORY;
        }
        return psf.params();
    }


    // ==== handling different parameter structures...
    private static final Map<XosFunctionDescriptor, ParamsFactory>
        PARAM_MAP = new HashMap<XosFunctionDescriptor, ParamsFactory>();

    private static final ParamsFactory DEF_PARAMS_FACTORY = new ParamsFactory();
    static {
        PARAM_MAP.put(URL_FILTER, new UrlFilterParamsFactory());
    }

    /**
     * Applies a parameter change for the given function, in the context of
     * the specified user.
     *
     * @param xfd function context
     * @param userId user identifier
     * @param param parameter name
     * @param value value to apply
     */
    public static void apply(XosFunctionDescriptor xfd, int userId,
                             String param, String value) {
        // TODO:
    }

    /**
     * Creates an object node representation of the profile for the
     * specified user.
     *
     * @param user the user
     * @return object node profile
     */
    public static ObjectNode profileForUser(SubscriberUser user) {
        ObjectNode root = objectNode();
        for (XosFunctionDescriptor xfd: XosFunctionDescriptor.values()) {
            XosFunction.Memento mem = user.getMemento(xfd);
            if (mem != null) {
                root.set(xfd.id(), mem.toObjectNode());
            }
        }
        return root;
    }


    // ===================================================================
    // === factories for creating parameter structures, both default
    //     and from a memento...

    // private parameter structure creator
    static class ParamsFactory {
        ObjectNode params() {
            return objectNode();
        }
    }

    static class UrlFilterParamsFactory extends ParamsFactory {
        @Override
        ObjectNode params() {
            ObjectNode result = objectNode();
            result.put(LEVEL, DEFAULT_FILTER_LEVEL.name());
            ArrayNode levels = arrayNode();
            for (UrlFilterFunction.Level lvl: UrlFilterFunction.Level.values()) {
                levels.add(lvl.name());
            }
            result.set(LEVELS, levels);
            return result;
        }
    }
}
