/**
 * Copyright 2014 Zaradai
 *
 * Licensed 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 com.zaradai.bloodstone.properties.expression;

import com.google.inject.Inject;
import com.zaradai.bloodstone.properties.ParameterManager;
import de.odysseus.el.ExpressionFactoryImpl;
import de.odysseus.el.util.SimpleContext;

import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
import javax.el.CompositeELResolver;
import javax.el.ExpressionFactory;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.ResourceBundleELResolver;
import javax.el.ValueExpression;

public class JuelConditionalEvaluator implements ConditionalEvaluator {
    private final ExpressionFactory factory;
    private final SimpleContext context;

    @Inject
    JuelConditionalEvaluator(final ParameterManager parameterManager) {
        factory = new ExpressionFactoryImpl();
        context = new SimpleContext(
                new CompositeELResolver() {
                    {
                        add(new ArrayELResolver(true));
                        add(new ListELResolver(true));
                        add(new MapELResolver(true));
                        add(new ParameterManagerResolver(parameterManager));
                        add(new ResourceBundleELResolver());
                        add(new BeanELResolver(true));
                    }
                }
        );
    }

    @Override
    public boolean parse(String condition) {
        ValueExpression ve = factory.createValueExpression(context, condition, boolean.class);
        Object value = ve.getValue(context);

        return (value instanceof Boolean) && (Boolean) value;
    }
}
