/*
 * 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.myfaces.extensions.validator.core.el;

import org.apache.myfaces.extensions.validator.internal.ToDo;
import org.apache.myfaces.extensions.validator.internal.Priority;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Iterator;

/**
 * Helper class to get the real/full value binding - tested with facelets 1.1.14
 * The target is to get rid of this impl. - currently it's a workaround to support custom facelets components.
 * An alternative would be an EL-Resolver - there are still some open issues with such an approach
 * + It isn't available with JSF 1.1.x
 *
 * @author Gerhard Petracek
 * @since 1.x.1
 */
@UsageInformation(UsageCategory.INTERNAL)
class FaceletsTaglibExpressionHelper
{
    public static ValueBindingExpression tryToCreateValueBindingForFaceletsBinding(UIComponent uiComponent)
    {
        String faceletsValueBindingExpression = DefaultELHelper.getOriginalValueBindingExpression(uiComponent);

        try
        {
            List<String> foundBindings = extractELTerms(
                ExtValUtils.getELHelper().getBindingOfComponent(uiComponent, "value"));

            Map<String, String> mappedFaceletsVars = new HashMap<String, String>();
            ValueBindingExpression vbe= new ValueBindingExpression(faceletsValueBindingExpression
                    .substring(0, 1) + "{" + createBinding(foundBindings, mappedFaceletsVars) + "}");

            Class entityClass = ExtValUtils.getELHelper()
                .getTypeOfExpression(FacesContext.getCurrentInstance(), vbe.getBaseExpression());

            if(entityClass == null)
            {
                return tryToReplaceVars(vbe, mappedFaceletsVars);
            }
            return vbe;
        }
        catch (Throwable t)
        {
            return new ValueBindingExpression(faceletsValueBindingExpression);
        }
    }

    @ToDo(value = Priority.MEDIUM, description = "logging")
    private static String createBinding(List<String> expressions, Map<String, String> virtualVars)
    {
        String currentBinding;

        int indexOfBindingDetails;
        String[] foundBindingDetails;
        String[] bindingDetails;

        Map<String, String> addedVirtualNames = new HashMap<String, String>();

        for (String entry : expressions)
        {
            if (entry.startsWith("ValueExpression["))
            {
                continue;
            }

            foundBindingDetails = entry.split(" ");
            indexOfBindingDetails = findIndexOfBindingDetails(foundBindingDetails);

            if (indexOfBindingDetails == -1)
            {
                return null;
            }

            bindingDetails = foundBindingDetails[indexOfBindingDetails].split("=");

            if (bindingDetails.length < 2)
            {
                return null;
            }

            currentBinding = bindingDetails[1];

            //to support blanks within a binding with map syntax
            if(currentBinding.contains("{") && !currentBinding.contains("}"))
            {
                currentBinding = addFurtherBindingParts(currentBinding, foundBindingDetails, indexOfBindingDetails);
            }

            if (currentBinding.contains("}"))
            {
                //entry for "virtual" facelets beans
                if(!addedVirtualNames.containsKey(bindingDetails[0]))
                {
                    addedVirtualNames.put(bindingDetails[0], currentBinding);
                }
            }
            //entry for "virtual" facelets var
            if(!(currentBinding.contains("{") || currentBinding.contains("}")))
            {
                virtualVars.put(bindingDetails[0], bindingDetails[1].substring(1, bindingDetails[1].length()-2));
            }
        }

        String originalBinding = addedVirtualNames.get("value");
        originalBinding = originalBinding.substring(originalBinding.indexOf("{") + 1, originalBinding.indexOf("}"));
        addedVirtualNames.remove("value");
        return tryToTransformToRealBinding(originalBinding, addedVirtualNames, virtualVars);
    }

    private static String tryToTransformToRealBinding(
            String originalBinding, Map<String, String> addedVirtualNames, Map<String, String> virtualVars)
    {
        originalBinding = "#{" + originalBinding + "}";
        Iterator nameIterator = addedVirtualNames.keySet().iterator();

        String currentKey;
        String currentValue;
        while(nameIterator.hasNext())
        {
            currentKey = (String) nameIterator.next();

            currentValue = addedVirtualNames.get(currentKey);
            currentValue = currentValue.substring(currentValue.indexOf("{") + 1, currentValue.indexOf("}"));

            originalBinding = originalBinding.replace("{" + currentKey + ".", "{" + currentValue + ".");
            //dynamic base and property
            originalBinding = originalBinding.replace("{" + currentKey + "[", "{" + currentValue + "[");

            originalBinding = originalBinding.replace("." + currentKey + ".", "." + currentValue + ".");
            //dynamic base and property
            originalBinding = originalBinding.replace("." + currentKey + "[", "." + currentValue + "[");

            originalBinding = originalBinding.replace("[" + currentKey + "]", "['" + currentValue + "']");
            //dynamic base and property
            originalBinding = originalBinding.replace("[" + currentKey + "[", "[" + currentValue + "[");
            originalBinding = originalBinding.replace("[" + currentKey + ".", "[" + currentValue + ".");
        }

        nameIterator = virtualVars.keySet().iterator();

        while(nameIterator.hasNext())
        {
            currentKey = (String) nameIterator.next();

            currentValue = virtualVars.get(currentKey);

            originalBinding = originalBinding.replace("{" + currentKey + ".", "{" + currentValue + ".");
            //dynamic base and property
            originalBinding = originalBinding.replace("{" + currentKey + "[", "{" + currentValue + "[");

            originalBinding = originalBinding.replace("." + currentKey + ".", "." + currentValue + ".");
            //dynamic base and property
            originalBinding = originalBinding.replace("." + currentKey + "[", "." + currentValue + "[");

            originalBinding = originalBinding.replace("[" + currentKey + "]", "['" + currentValue + "']");
            //dynamic base and property
            originalBinding = originalBinding.replace("[" + currentKey + "[", "[" + currentValue + "[");
            originalBinding = originalBinding.replace("[" + currentKey + ".", "[" + currentValue + ".");
        }

        return originalBinding.substring(2, originalBinding.length() - 1);
    }

    //to support blanks - e.g. with map syntax
    private static String addFurtherBindingParts(String currentBinding, String[] foundBindingDetails,
                                                 int indexOfBindingDetails)
    {
        for(int i = indexOfBindingDetails + 1; i < foundBindingDetails.length; i++)
        {
            currentBinding += foundBindingDetails[i];
            if(foundBindingDetails[i].contains("}"))
            {
                return currentBinding;
            }
        }
        return currentBinding;
    }

    private static int findIndexOfBindingDetails(String[] bindingDetails)
    {
        int count = 0;
        for (String entry : bindingDetails)
        {
            if (entry.contains("="))
            {
                return count;
            }
            count++;
        }
        return -1;
    }

    private static List<String> extractELTerms(Object o)
    {
        List<String> foundELTerms = new ArrayList<String>();
        try
        {
            if (resolveELTerms(o, new HashMap<Object, Object>(), foundELTerms, 0) > 0)
            {
                return foundELTerms;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        return null;
    }

    private static int resolveELTerms(Object o, Map<Object, Object> visited,
                                      List<String> foundELTerms, int count) throws Exception
    {
        if (o == null || visited.containsKey(o) || count > 50)
        {
            return 0;
        }

        visited.put(o, null);

        int elCount = 0;
        Class c = o.getClass();

        //inspect maps
        if (o instanceof Map)
        {

            for (Object entry : ((Map) o).values())
            {
                //found entry for "virtual" facelets var
                if(entry.toString().contains("ValueExpression["))
                {
                    foundELTerms.add(entry.toString());
                }
                elCount += resolveELTerms(entry, visited, foundELTerms, count + 1);
            }
            return elCount;
        }

        if (ExtValUtils.getELHelper().isELTermWellFormed(o))
        {
            if (foundELTerms != null)
            {
                foundELTerms.add(o.toString());
            }
            return ++elCount;
        }

        //analyze arrays
        if (c.isArray())
        {
            int length = Array.getLength(o);
            //check array [L -> no array of primitive types
            if (o.toString().startsWith("[L"))
            {
                for (int i = 0; i < length; i++)
                {
                    if (o.toString().startsWith("[Ljava.lang.String"))
                    {
                        if (ExtValUtils.getELHelper().isELTermWellFormed(Array.get(o, i)))
                        {
                            if (foundELTerms != null)
                            {
                                foundELTerms.add(o.toString());
                            }
                            elCount++;
                        }
                    }
                    else
                    {
                        elCount += resolveELTerms(Array.get(o, i), visited, foundELTerms, count + 1);
                    }
                }
            }
            return elCount;
        }

        List<Field> attributes = findAllAttributes(c, new ArrayList<Field>());
        Field[] fields = attributes.toArray(new Field[attributes.size()]);

        AccessibleObject.setAccessible(fields, true);
        for (Field currentField : fields)
        {
            if (currentField.get(o) == null)
            {
                continue;
            }

            if (currentField.getType().equals(String.class))
            {
                if (currentField.get(o) != null && ExtValUtils.getELHelper().isELTermWellFormed(currentField.get(o)))
                {
                    if (foundELTerms != null)
                    {
                        foundELTerms.add(o.toString());
                    }
                    elCount++;
                }
            }
            else if (!currentField.getType().isPrimitive())
            {
                elCount += resolveELTerms(currentField.get(o), visited, foundELTerms, count + 1);
            }
        }
        return elCount;
    }

    private static List<Field> findAllAttributes(Class c, List<Field> attributes)
    {
        if (c == null)
        {
            return attributes;
        }
        findAllAttributes(c.getSuperclass(), attributes);

        Field[] fields = c.getDeclaredFields();
        for (Field currentField : fields)
        {
            if (!Modifier.isStatic(currentField.getModifiers()))
            {
                attributes.add(currentField);
            }
        }

        return attributes;
    }

    private static ValueBindingExpression tryToReplaceVars(ValueBindingExpression valueBindingExpression,
                                                            Map<String, String> mappedFaceletsVars)
    {
        String property;
        String result = "";
        boolean last = false;

        while(true)
        {
            if(valueBindingExpression.getBaseExpression() == null)
            {
                last = true;
            }


            property = valueBindingExpression.getProperty();

            valueBindingExpression = ValueBindingExpression
                .replaceProperty(valueBindingExpression, getNewProperty(property, mappedFaceletsVars));

            if(result.length() == 0)
            {
                result = valueBindingExpression.getProperty();
            }
            else
            {
                result = valueBindingExpression.getProperty() + "." + result;
            }

            valueBindingExpression = valueBindingExpression.getBaseExpression();

            if(last)
            {
                break;
            }
        }
        return new ValueBindingExpression(valueBindingExpression.getPrefix() + "{" + result + "}");
    }

    private static String getNewProperty(String oldProperty, Map<String, String> mappedFaceletsVars)
    {
        List<String> virtualVars = getPotentialVirtualVars(oldProperty);

        for(String virtualVar : virtualVars)
        {
            if(mappedFaceletsVars.containsKey(virtualVar))
            {
                oldProperty = replacePropertyValue(oldProperty, virtualVar, mappedFaceletsVars.get(virtualVar));
            }
        }
        return oldProperty;
    }

    private static List<String> getPotentialVirtualVars(String oldProperty)
    {
        int start = -1;
        int end = -1;

        List<String> virtualVarList = new ArrayList<String>();

        for(int i = 0; i < oldProperty.length(); i++)
        {
            if(start == - 1 && oldProperty.charAt(i) == '[')
            {
                start = i + 1;
            }
            else if((start != - 1 && oldProperty.charAt(i) == '[') || oldProperty.charAt(i) == ']')
            {
                end = i;
            }

            if(start != -1 && end != -1)
            {
                virtualVarList.add(oldProperty.substring(start, end));
                if(oldProperty.charAt(i) == '[')
                {
                    start = i + 1;
                }
                else
                {
                    start = -1;
                }
                end = -1;
            }
        }

        return virtualVarList;
    }

    private static String replacePropertyValue(String oldProperty, String targetVar, String newValue)
    {
        int index = oldProperty.indexOf(targetVar);

        if(index == -1)
        {
            return oldProperty;
        }

        String result = oldProperty.substring(0, index);
        result += newValue;
        return result + oldProperty.substring(index + targetVar.length(), oldProperty.length());
    }

    /*
     * replace virtual facelets vars (map syntax)
     * tested styles (simple and nested): test[ix[ix2[ix3]]]
     */
    /*
    private static String _createBinding(List<String> expressions, Map<String, String> virtualVars)
    {
        String result = "";

        String prevFaceletsAttributeName = null;
        String currentBinding;
        String partOfBinding;

        int indexOfBindingDetails;
        String[] foundBindingDetails;
        String[] bindingDetails;

        List<String> addedVirtualNames = new ArrayList<String>();

        for (String entry : expressions)
        {
            if (entry.startsWith("ValueExpression["))
            {
                continue;
            }

            foundBindingDetails = entry.split(" ");
            indexOfBindingDetails = findIndexOfBindingDetails(foundBindingDetails);

            if (indexOfBindingDetails == -1)
            {
                return null;
            }

            bindingDetails = foundBindingDetails[indexOfBindingDetails].split("=");

            if (bindingDetails.length < 2)
            {
                return null;
            }

            currentBinding = bindingDetails[1];

            //to support blanks within a binding with map syntax
            if(currentBinding.contains("{") && !currentBinding.contains("}"))
            {
                currentBinding = addFurtherBindingParts(currentBinding, foundBindingDetails, indexOfBindingDetails);
            }

            if (prevFaceletsAttributeName != null && currentBinding.contains("}"))
            {
                //entry for "virtual" facelets beans
                if(!addedVirtualNames.contains(bindingDetails[0]))
                {
                    partOfBinding = currentBinding.substring(currentBinding.indexOf(prevFaceletsAttributeName)
                        + prevFaceletsAttributeName.length(), currentBinding.indexOf("}"));

                    addedVirtualNames.add(bindingDetails[0]);
                    result = result + partOfBinding;
                }
                else
                {
                    continue;
                }
            }
            //entry for "virtual" facelets var
            else if(!(currentBinding.contains("{") || currentBinding.contains("}")))
            {
                virtualVars.put(bindingDetails[0], bindingDetails[1].substring(1, bindingDetails[1].length()-2));
                continue;
            }
            else
            {
                if(!addedVirtualNames.contains(bindingDetails[0]))
                {
                    addedVirtualNames.add(bindingDetails[0]);
                    result = currentBinding.substring(currentBinding.indexOf("{") + 1, currentBinding.indexOf("}"));
                }
            }

            prevFaceletsAttributeName = bindingDetails[0];
        }
        return result;
    }
    */
}
