/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.scxml2;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.scxml2.env.groovy.GroovyEvaluator;
import org.apache.commons.scxml2.env.javascript.JSEvaluator;
import org.apache.commons.scxml2.env.jexl.JexlEvaluator;
import org.apache.commons.scxml2.env.minimal.MinimalEvaluator;
import org.apache.commons.scxml2.model.ModelException;
import org.apache.commons.scxml2.model.SCXML;
import static org.apache.commons.scxml2.Evaluator.DEFAULT_DATA_MODEL;

/**
 * A static singleton factory for {@link EvaluatorProvider}s by supported SCXML datamodel type.
 * <p>
 *  The EvaluatorFactory is used to automatically create an {@link Evaluator} instance for an SCXML
 *  statemachine when none has been pre-defined and configured for the {@link SCXMLExecutor}.
 * </p>
 * <p>
 *  The builtin supported providers are:
 * </p>
 * <ul>
 *  <li>no or empty datamodel (default) or datamodel="jexl": {@link JexlEvaluator.JexlEvaluatorProvider}</li>
 *  <li>datamodel="ecmascript": {@link JSEvaluator.JSEvaluatorProvider}</li>
 *  <li>datamodel="groovy": {@link GroovyEvaluator.GroovyEvaluatorProvider}</li>
 *  <li>datamodel="null": {@link MinimalEvaluator.MinimalEvaluatorProvider}</li>
 * </ul>
 * <p>
 *  For adding additional or overriding the builtin Evaluator implementations use
 *  {@link #registerEvaluatorProvider(EvaluatorProvider)} or {@link #unregisterEvaluatorProvider(String)}.
 * </p>
 * <p>
 *  The default provider can be overridden using the {@link #setDefaultProvider(EvaluatorProvider)} which will
 *  register the provider under the {@link Evaluator#DEFAULT_DATA_MODEL} ("") value for the datamodel.<br>
 *  Note: this is <em>not</em> the same as datamodel="null"!
 * </p>
 */
public class EvaluatorFactory {

    private static EvaluatorFactory INSTANCE = new EvaluatorFactory();

    private final Map<String, EvaluatorProvider> providers = new ConcurrentHashMap<>();

    private EvaluatorFactory() {
        providers.put(JSEvaluator.SUPPORTED_DATA_MODEL, new JSEvaluator.JSEvaluatorProvider());
        providers.put(GroovyEvaluator.SUPPORTED_DATA_MODEL, new GroovyEvaluator.GroovyEvaluatorProvider());
        providers.put(JexlEvaluator.SUPPORTED_DATA_MODEL, new JexlEvaluator.JexlEvaluatorProvider());
        providers.put(MinimalEvaluator.SUPPORTED_DATA_MODEL, new MinimalEvaluator.MinimalEvaluatorProvider());
        providers.put(DEFAULT_DATA_MODEL, providers.get(JexlEvaluator.SUPPORTED_DATA_MODEL));
    }

    public static void setDefaultProvider(EvaluatorProvider defaultProvider) {
        INSTANCE.providers.put(DEFAULT_DATA_MODEL, defaultProvider);
    }

    @SuppressWarnings("unused")
    public static EvaluatorProvider getDefaultProvider() {
        return INSTANCE.providers.get(DEFAULT_DATA_MODEL);
    }

    @SuppressWarnings("unused")
    public static EvaluatorProvider getEvaluatorProvider(String datamodelName) {
        return INSTANCE.providers.get(datamodelName == null ? DEFAULT_DATA_MODEL : datamodelName);
    }

    @SuppressWarnings("unused")
    public static void registerEvaluatorProvider(EvaluatorProvider provider) {
        INSTANCE.providers.put(provider.getSupportedDatamodel(), provider);
    }

    @SuppressWarnings("unused")
    public static void unregisterEvaluatorProvider(String datamodelName) {
        INSTANCE.providers.remove(datamodelName == null ? DEFAULT_DATA_MODEL : datamodelName);
    }

    /**
     * Returns a dedicated Evaluator instance for a specific SCXML document its documentmodel.
     * <p>If no SCXML document is provided a default Evaluator will be returned.</p>
     * @param document The document to return a dedicated Evaluator for. May be null to retrieve the default Evaluator.
     * @return a new and not sharable Evaluator instance for the provided document, or a default Evaluator otherwise
     * @throws ModelException If the SCXML document datamodel is not supported.
     */
    public static Evaluator getEvaluator(SCXML document) throws ModelException {
        String datamodelName = document != null ? document.getDatamodelName() : null;
        EvaluatorProvider provider = INSTANCE.providers.get(datamodelName == null ? DEFAULT_DATA_MODEL : datamodelName);
        if (provider == null) {
            throw new ModelException("Unsupported SCXML document datamodel \""+(datamodelName)+"\"");
        }
        return document != null ? provider.getEvaluator(document) : provider.getEvaluator();
    }
}
