/*******************************************************************************
 * 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.ofbiz.base.util.string;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.PropertyNotFoundException;
import javax.el.PropertyNotWritableException;
import javax.el.ResourceBundleELResolver;
import javax.el.ValueExpression;
import javax.el.VariableMapper;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.collections.LocalizedMap;

/** Implements the Unified Expression Language (JSR-245). */
public class UelUtil {
    protected static final String module = UelUtil.class.getName();
    public static final String localizedMapLocaleKey = LocalizedMap.class.getName() + "_locale".replace(".", "_");
    protected static final ExpressionFactory exprFactory = JuelConnector.newExpressionFactory();
    protected static final ELResolver defaultResolver = new ExtendedCompositeResolver() {
        {
            add(new ExtendedMapResolver(false));
            add(new ExtendedListResolver(false));
            add(new ArrayELResolver(false));
            add(new NodeELResolver()); // Below the most common but must be kept above BeanELResolver
            add(new ResourceBundleELResolver());
            add(new BeanELResolver(false));
        }
    };

    /** Evaluates a Unified Expression Language expression and returns the result.
     * @param context Evaluation context (variables)
     * @param expression UEL expression
     * @return Result object
     * @throws <code>javax.el.*</code> exceptions
     */
    public static Object evaluate(Map<String, ? extends Object> context, String expression) {
        return evaluate(context, expression, Object.class);
    }

    /** Evaluates a Unified Expression Language expression and returns the result.
     * @param context Evaluation context (variables)
     * @param expression UEL expression
     * @param expectedType The expected object Class to return
     * @return Result object
     * @throws <code>javax.el.*</code> exceptions
     */
    @SuppressWarnings("unchecked")
    public static Object evaluate(Map<String, ? extends Object> context, String expression, Class expectedType) {
        ELContext elContext = new ReadOnlyContext(context);
        ValueExpression ve = exprFactory.createValueExpression(elContext, expression, expectedType);
        return ve.getValue(elContext);
    }

    /** Evaluates a Unified Expression Language expression and sets the resulting object
     * to the specified value.
     * @param context Evaluation context (variables)
     * @param expression UEL expression
     * @param expectedType The expected object Class to set
     * @throws <code>javax.el.*</code> exceptions
     */
    @SuppressWarnings("unchecked")
    public static void setValue(Map<String, Object> context, String expression, Class expectedType, Object value) {
        if (Debug.verboseOn()) {
            Debug.logVerbose("UelUtil.setValue invoked, expression = " + expression + ", value = " + value, module);
        }
        ELContext elContext = new BasicContext(context);
        ValueExpression ve = exprFactory.createValueExpression(elContext, expression, expectedType);
        ve.setValue(elContext, value);
    }

    /** Evaluates a Unified Expression Language expression and sets the resulting object
     * to null.
     * @param context Evaluation context (variables)
     * @param expression UEL expression
     * @throws <code>javax.el.*</code> exceptions
     */
    public static void removeValue(Map<String, Object> context, String expression) {
        if (Debug.verboseOn()) {
            Debug.logVerbose("UelUtil.removeValue invoked, expression = " + expression , module);
        }
        ELContext elContext = new BasicContext(context);
        ValueExpression ve = exprFactory.createValueExpression(elContext, expression, Object.class);
        ve.setValue(elContext, null);
    }

    protected static class BasicContext extends ELContext {
        protected final Map<String, Object> variables;
        protected final VariableMapper variableMapper;
        public BasicContext(Map<String, Object> context) {
            this.variableMapper = new BasicVariableMapper(this);
            this.variables = context;
        }
        @Override
        public ELResolver getELResolver() {
            return defaultResolver;
        }
        @Override
        public FunctionMapper getFunctionMapper() {
            return UelFunctions.getFunctionMapper();
        }
        @Override
        public VariableMapper getVariableMapper() {
            return this.variableMapper;
        }
    }

    protected static class ReadOnlyContext extends ELContext {
        protected final Map<String, ? extends Object> variables;
        protected final VariableMapper variableMapper;
        public ReadOnlyContext(Map<String, ? extends Object> context) {
            this.variableMapper = new ReadOnlyVariableMapper(this);
            this.variables = UtilGenerics.cast(context);
        }
        @Override
        public ELResolver getELResolver() {
            return defaultResolver;
        }
        @Override
        public FunctionMapper getFunctionMapper() {
            return UelFunctions.getFunctionMapper();
        }
        @Override
        public VariableMapper getVariableMapper() {
            return this.variableMapper;
        }
        protected static class ReadOnlyVariableMapper extends VariableMapper {
            protected final ReadOnlyContext elContext;
            protected ReadOnlyVariableMapper(ReadOnlyContext elContext) {
                this.elContext = elContext;
            }
            @Override
            public ValueExpression resolveVariable(String variable) {
                Object obj = UelUtil.resolveVariable(variable, this.elContext.variables, null);
                if (obj != null) {
                    return new ReadOnlyExpression(obj);
                }
                return null;
            }
            @Override
            public ValueExpression setVariable(String variable, ValueExpression expression) {
                throw new PropertyNotWritableException();
            }
        }
    }

    protected static class BasicVariableMapper extends VariableMapper {
        protected final BasicContext elContext;
        protected BasicVariableMapper(BasicContext elContext) {
            this.elContext = elContext;
        }

        /**
         * Returns a BasicValueExpression containing the value of the named variable.
         * Resolves against LocalizedMap if available.
         * @param variable the variable's name
         * @return a BasicValueExpression containing the variable's value or null if the variable is unknown
         */
        @Override
        public ValueExpression resolveVariable(String variable) {
            Object obj = UelUtil.resolveVariable(variable, this.elContext.variables, null);
            if (obj != null) {
                return new BasicValueExpression(variable, this.elContext);
            }
            return null;
        }
        @Override
        public ValueExpression setVariable(String variable, ValueExpression expression) {
            Object originalObj = this.elContext.variables.put(variable, expression.getValue(this.elContext));
            if (originalObj == null) {
                return null;
            }
            return new ReadOnlyExpression(originalObj);
        }
    }

    @SuppressWarnings("serial")
    protected static class ReadOnlyExpression extends ValueExpression {
        protected final Object object;
        protected ReadOnlyExpression(Object object) {
            this.object = object;
        }

        @Override
        public Class<?> getExpectedType() {
            return this.object.getClass();
        }

        @Override
        public Class<?> getType(ELContext context) {
            return this.getExpectedType();
        }

        @Override
        public Object getValue(ELContext context) {
            return this.object;
        }

        @Override
        public boolean isReadOnly(ELContext context) {
            return true;
        }

        @Override
        public void setValue(ELContext context, Object value) {
            throw new PropertyNotWritableException();
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            try {
                ReadOnlyExpression other = (ReadOnlyExpression) obj;
                return this.object.equals(other.object);
            } catch (ClassCastException e) {}
            return false;
        }

        @Override
        public String getExpressionString() {
            return null;
        }

        @Override
        public int hashCode() {
            return this.object.hashCode();
        }

        @Override
        public boolean isLiteralText() {
            return false;
        }
        
    }

    @SuppressWarnings("serial")
    protected static class BasicValueExpression extends ValueExpression {
        protected final BasicContext elContext;
        protected final String varName;
        public BasicValueExpression(String varName, BasicContext elContext) {
            this.elContext = elContext;
            this.varName = varName;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            try {
                BasicValueExpression other = (BasicValueExpression) obj;
                return this.varName.equals(other.varName);
            } catch (ClassCastException e) {}
            return false;
        }
        @Override
        public int hashCode() {
            return this.varName.hashCode();
        }
        @Override
        public Object getValue(ELContext context) {
            return this.elContext.variables.get(this.varName);
        }
        @Override
        public String getExpressionString() {
            return null;
        }
        @Override
        public boolean isLiteralText() {
            return false;
        }
        @Override
        public Class<?> getType(ELContext context) {
            return this.getExpectedType();
        }
        @Override
        public boolean isReadOnly(ELContext context) {
            return false;
        }
        @Override
        public void setValue(ELContext context, Object value) {
            this.elContext.variables.put(this.varName, value);
        }
        @Override
        public String toString() {
            return "ValueExpression(" + this.varName + ")";
        }
        @Override
        public Class<?> getExpectedType() {
            Object obj = this.elContext.variables.get(this.varName);
            return obj == null ? null : obj.getClass();
        }
    }

    /** Custom <code>CompositeELResolver</code> used to handle variable
     * auto-vivify.
     */
    protected static class ExtendedCompositeResolver extends CompositeELResolver {
        @Override
        public void setValue(ELContext context, Object base, Object property, Object val) {
            super.setValue(context, base, property, val);
            if (!context.isPropertyResolved() && base == null) {
                if (Debug.verboseOn()) {
                    Debug.logVerbose("ExtendedCompositeResolver.setValue: base = " + base + ", property = " + property + ", value = " + val, module);
                }
                try {
                    BasicContext elContext = (BasicContext) context;
                    elContext.variables.put(property.toString(), val);
                    context.setPropertyResolved(true);
                } catch (ClassCastException e) {}
            }
        }
    }

    /** Custom <code>ListELResolver</code> used to handle OFBiz
     * <code>List</code> syntax.
     */
    protected static class ExtendedListResolver extends ListELResolver {
        protected boolean isReadOnly;
        public ExtendedListResolver(boolean isReadOnly) {
            super(isReadOnly);
            this.isReadOnly = isReadOnly;
        }
        @Override
        @SuppressWarnings("unchecked")
        public void setValue(ELContext context, Object base, Object property, Object val) {
            if (context == null) {
                throw new NullPointerException();
            }
            if (base != null && base instanceof List) {
                if (isReadOnly) {
                    throw new PropertyNotWritableException();
                }
                String str = property.toString();
                if ("add".equals(str)) {
                    if (Debug.verboseOn()) {
                        Debug.logVerbose("ExtendedListResolver.setValue adding List element: base = " + base + ", property = " + property + ", value = " + val, module);
                    }
                    context.setPropertyResolved(true);
                    List list = (List) base;
                    list.add(val);
                } else if (str.startsWith("insert@")) {
                    if (Debug.verboseOn()) {
                        Debug.logVerbose("ExtendedListResolver.setValue inserting List element: base = " + base + ", property = " + property + ", value = " + val, module);
                    }
                    context.setPropertyResolved(true);
                    String indexStr = str.replace("insert@", "");
                    int index = Integer.parseInt(indexStr);
                    List list = (List) base;
                    try {
                        list.add(index, val);
                    } catch (UnsupportedOperationException ex) {
                        throw new PropertyNotWritableException();
                    } catch (IndexOutOfBoundsException ex) {
                        throw new PropertyNotFoundException();
                    }
                } else {
                    super.setValue(context, base, property, val);
                }
            }
        }
    }

    /** Custom <code>MapELResolver</code> class used to accommodate
     * <code>LocalizedMap</code> instances.
     */
    protected static class ExtendedMapResolver extends MapELResolver {
        public ExtendedMapResolver(boolean isReadOnly) {
            super(isReadOnly);
        }
        @Override
        @SuppressWarnings("unchecked")
        public Object getValue(ELContext context, Object base, Object property) {
            if (context == null) {
                throw new NullPointerException();
            }
            if (base != null && base instanceof LocalizedMap) {
                context.setPropertyResolved(true);
                LocalizedMap map = (LocalizedMap) base;
                Locale locale = null;
                try {
                    VariableMapper vm = context.getVariableMapper();
                    ValueExpression ve = vm.resolveVariable(localizedMapLocaleKey);
                    if (ve != null) {
                        locale = (Locale) ve.getValue(context);
                    }
                    if (locale == null) {
                        ve = vm.resolveVariable("locale");
                        if (ve != null) {
                            locale = (Locale) ve.getValue(context);
                        }
                    }
                } catch (Exception e) {
                    Debug.logWarning("Exception thrown while getting LocalizedMap element, locale = " + locale + ", exception " + e, module);
                }
                if (locale == null) {
                    if (Debug.verboseOn()) {
                        Debug.logVerbose("ExtendedMapResolver.getValue: unable to find Locale for LocalizedMap element, using default locale", module);
                    }
                    locale = Locale.getDefault();
                }
                return resolveVariable(property.toString(), (Map) map, locale);
            }
            if (base != null && base instanceof Map && property instanceof String) {
                context.setPropertyResolved(true);
                return resolveVariable(property.toString(), (Map) base, null);
            }
            return super.getValue(context, base, property);
        }
    }

    /** Evaluates a property <code>Object</code> and returns a new
     * <code>List</code> or <code>Map</code>. If <code>property</code>
     * is not a String object type and it evaluates to an integer value,
     * a new <code>List</code> instance is returned, otherwise a new
     * <code>Map</code> instance is returned.
     * @param property Property <code>Object</code> to be evaluated
     * @return New <code>List</code> or <code>Map</code>
     */
    @SuppressWarnings("rawtypes")
    public static Object autoVivifyListOrMap(Object property) {
        String str = property.toString();
        boolean isList = ("add".equals(str) || str.startsWith("insert@"));
        if (!isList && !"java.lang.String".equals(property.getClass().getName())) {
            Integer index = UtilMisc.toIntegerObject(property);
            isList = (index != null);
        }
        if (isList) {
            return new LinkedList();
        } else {
            return new HashMap();
        }
    }

    /** Prepares an expression for evaluation by UEL.<p>The OFBiz syntax is
     * converted to UEL-compatible syntax and the resulting expression is
     * returned.</p>
     * @see <a href="StringUtil.html#convertOperatorSubstitutions(java.lang.String)">StringUtil.convertOperatorSubstitutions(java.lang.String)</a>
     * @param expression Expression to be converted
     * @return Converted expression
     */
    public static String prepareExpression(String expression) {
        String result = StringUtil.convertOperatorSubstitutions(expression);
        result = result.replace("[]", "['add']");
        int openBrace = result.indexOf("[+");
        int closeBrace = (openBrace == -1 ? -1 : result.indexOf(']', openBrace));
        if (closeBrace != -1) {
            String base = result.substring(0, openBrace);
            String property = result.substring(openBrace+2, closeBrace).trim();
            String end = result.substring(closeBrace + 1);
            result = base + "['insert@" + property + "']" + end;
        }
        return result;
    }

    public static Object resolveVariable(String variable, Map<String, ? extends Object> variables, Locale locale) {
        Object obj = null;
        String createObjectType = null;
        String name = variable;
        if (variable.contains("$")) {
            if (variable.endsWith("$string")) {
                name = variable.substring(0, variable.length() - 7);
                createObjectType = "string";
            } else if (variable.endsWith("$null")) {
                name = variable.substring(0, variable.length() - 5);
                createObjectType = "null";
            } else if (variable.endsWith("$boolean")) {
                name = variable.substring(0, variable.length() - 8);
                createObjectType = "boolean";
            } else if (variable.endsWith("$integer")) {
                name = variable.substring(0, variable.length() - 8);
                createObjectType = "integer";
            } else if (variable.endsWith("$long")) {
                name = variable.substring(0, variable.length() - 5);
                createObjectType = "long";
            } else if (variable.endsWith("$double")) {
                name = variable.substring(0, variable.length() - 7);
                createObjectType = "double";
            } else if (variable.endsWith("$bigDecimal")) {
                name = variable.substring(0, variable.length() - 11);
                createObjectType = "bigDecimal";
            }
        }
        if (variables instanceof LocalizedMap<?>) {
            if (locale == null) {
                locale = (Locale) variables.get(localizedMapLocaleKey);
                if (locale == null) {
                    locale = (Locale) variables.get("locale");
                    if (locale == null) {
                        locale = Locale.getDefault();
                    }
                }
            }
            obj = ((LocalizedMap<?>) variables).get(name, locale);
        } else {
            obj = variables.get(name);
        }
        if (obj != null) {
            return obj;
        }
        if (createObjectType != null) {
            if ("string".equals(createObjectType)) {
                return "";
            } else if ("null".equals(createObjectType)) {
                return null;
            } else if ("boolean".equals(createObjectType)) {
                return Boolean.FALSE;
            } else if ("integer".equals(createObjectType)) {
                return Integer.valueOf(0);
            } else if ("long".equals(createObjectType)) {
                return Long.valueOf(0);
            } else if ("double".equals(createObjectType)) {
                return Double.valueOf(0);
            } else if ("bigDecimal".equals(createObjectType)) {
                return BigDecimal.ZERO;
            }
        }
        return null;
    }

}
