/*******************************************************************************
 * Copyright (c) 2008, 2020 SAP AG and IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    SAP AG - initial API and implementation
 *    Andrew Johnson - array indexing and wrapping
 *******************************************************************************/
package org.eclipse.mat.parser.internal.oql.compiler;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.parser.internal.Messages;
import org.eclipse.mat.snapshot.model.Field;
import org.eclipse.mat.snapshot.model.FieldDescriptor;
import org.eclipse.mat.snapshot.model.IClass;
import org.eclipse.mat.snapshot.model.IObject;
import org.eclipse.mat.util.MessageUtil;

class PathExpression extends Expression
{
    private static class ArrayWrapper extends AbstractList<Object> {
        private final Object element;
        public ArrayWrapper(Object element) {
            this.element = element;
        }
        @Override
        public Object get(int i)
        {
            return Array.get(element, i);
        }

        @Override
        public int size()
        {
            return Array.getLength(element);
        }
        
        /*
         * Could override toString as but it can be useful to see the contents
         * element.getClass().getComponentType().getSimpleName()+'['+size()+']';
         */
    };
    
    private List<Object> attributes;

    public PathExpression(List<Object> attributes)
    {
        this.attributes = attributes;
    }

    @Override
    public Object compute(EvaluationContext ctx) throws SnapshotException
    {
        try
        {
            Object current = null;
            int index = 0;

            // check for alias
            Object firstItem = attributes.get(0);
            if (firstItem instanceof Attribute)
            {
                Attribute firstAttribute = (Attribute) firstItem;
                current = !firstAttribute.isNative() ? ctx.getAlias(firstAttribute.getName()) : null;
                if (current != null || !firstAttribute.isNative() && ctx.isAlias(firstAttribute.getName()))
                {
                    // We retrieved an alias (or snapshot) from the attribute, even if it was null, so advance
                    index++;
                }
            }

            if (index == 0)
                current = ctx.getSubject();

            for (; index < this.attributes.size(); index++)
            {
                if (current == null)
                    break;
                Object element = this.attributes.get(index);

                if (element != null && element.getClass().isArray())
                    element = asList(element);

                if (element instanceof Attribute)
                {
                    Attribute attribute = (Attribute) element;
                    if (attribute.isNative() || !(current instanceof IObject))
                    {
                        // special: we support the 'length' property for arrays
                        if (current.getClass().isArray())
                        {
                            if ("length".equals(attribute.getName())) //$NON-NLS-1$
                            {
                                current = Array.getLength(current);
                            }
                            else
                            {
                                throw new SnapshotException(MessageUtil.format(
                                                Messages.PathExpression_Error_ArrayHasNoProperty, new Object[] {
                                                                current.getClass().getComponentType().getName(),
                                                                attribute.name }));
                            }
                        }
                        else
                        {
                            boolean didFindProperty = false;

                            if (!attribute.isNative())
                            {
                                // Used for table rows from sub-select
                                if (current instanceof  Map<?,?>)
                                {
                                    Map<?,?> map = (Map<?,?>)current;
                                    current = map.get(attribute.getName());
                                    didFindProperty = true;
                                }
                            }

                            if (!didFindProperty)
                            {
                                BeanInfo info = Introspector.getBeanInfo(current.getClass());
                                PropertyDescriptor[] descriptors = info.getPropertyDescriptors();

                                for (PropertyDescriptor descriptor : descriptors)
                                {
                                    if (attribute.getName().equals(descriptor.getName()))
                                    {
                                        Method method = descriptor.getReadMethod();
                                        // Perhaps the method should be accessible via an interface, so try that first
                                        boolean useInterface = false;
                                        for (Class<?> intf : method.getDeclaringClass().getInterfaces())
                                        {
                                            try
                                            {
                                                // Avoid some NoSuchMethodExceptions by checking the name and number of parms first
                                                for (Method m3 : intf.getMethods())
                                                {
                                                    if (!m3.getName().equals(method.getName()))
                                                        continue;
                                                    if (m3.getParameterCount() != method.getParameterTypes().length)
                                                        continue;
                                                    Method m2 = intf.getMethod(method.getName(), method.getParameterTypes());
                                                    MethodCallExpression.checkMethodAccess(m2);
                                                    // Switching to the interface method
                                                    method = m2;
                                                    // Indicate found
                                                    useInterface = true;
                                                    break;
                                                }
                                            }
                                            catch (NoSuchMethodException e1)
                                            {
                                            }
                                            catch (SecurityException e1)
                                            {
                                            }
                                            if (useInterface)
                                                break;
                                        }
                                        if (!useInterface)
                                        {
                                            try
                                            {
                                                // Check whether access to this method should be allowed
                                                MethodCallExpression.checkMethodAccess(method);
                                            }
                                            catch (SecurityException e)
                                            {
                                                // Fail for the original reason
                                                throw new SnapshotException(MessageUtil.format(
                                                                Messages.PathExpression_Error_TypeHasNoProperty,
                                                                new Object[] { current.getClass().getName(),
                                                                                attribute.name }),
                                                                e);
                                            }
                                        }
                                        current = method.invoke(current, (Object[]) null);
                                        didFindProperty = true;
                                        break;
                                    }
                                }
                            }

                            if (!didFindProperty) { throw new SnapshotException(MessageUtil.format(
                                            Messages.PathExpression_Error_TypeHasNoProperty, new Object[] {
                                                            current.getClass().getName(), attribute.name })); }
                        }

                    }
                    else
                    {
                        IObject c = (IObject) current;
                        // Performance optimization - check that the field exists first
                        boolean found = false;
                        field: for (IClass cls = c.getClazz(); cls != null; cls = cls.getSuperClass())
                        {
                            for (FieldDescriptor fd : cls.getFieldDescriptors())
                            {
                                if (fd.getName().equals(attribute.getName()))
                                {
                                    found = true;
                                    break field;
                                }
                            }
                        }
                        if (found)
                        {
                            current = c.resolveValue(attribute.getName());
                        }
                        else
                        {
                            if (current instanceof IClass)
                            {
                                field: for (IClass cls = (IClass)current; cls != null; cls = cls.getSuperClass())
                                {
                                    for (Field f : cls.getStaticFields()) {
                                        if (f.getName().equals(attribute.getName())) {
                                            current = f.getValue();
                                            found = true;
                                            break field;
                                        }
                                    }
                                }
                            }
                            if (!found)
                            {
                                current = null;
                            }
                        }
                    }
                }
                else if (element instanceof Expression)
                {
                    EvaluationContext methodCtx = new EvaluationContext(ctx);
                    methodCtx.setSubject(current);
                    current = ((Expression) element).compute(methodCtx);
                }
                else
                {
                    throw new SnapshotException(MessageUtil.format(Messages.PathExpression_Error_UnknownElementInPath,
                                    new Object[] { element }));
                }

                if (current == null)
                    break;
            }

            return current;
        }
        catch (Exception e)
        {
            throw SnapshotException.rethrow(e);
        }
    }

    protected static List<?> asList(final Object element)
    {
        int size = Array.getLength(element);
        final boolean wrap = true;
        List<Object> answer;

        if (wrap)
        {
            // Wrap the original array
            answer = new ArrayWrapper(element);
        }
        else
        {
            // Make a copy of the array
            answer = new ArrayList<Object>(size);
            for (int ii = 0; ii < size; ii++)
                answer.add(Array.get(element, ii));
        }

        return answer;
    }

    @Override
    public boolean isContextDependent(EvaluationContext ctx)
    {
        Object firstItem = attributes.get(0);
        if (firstItem instanceof Attribute)
        {
            Attribute firstAttribute = (Attribute) firstItem;
            if (!firstAttribute.isNative() && ctx.isAlias(firstAttribute.getName()))
                return true;
        }
        else if (firstItem instanceof Expression)
        {
            if (((Expression) firstItem).isContextDependent(ctx))
                return true;
        }
        for (int i = 1; i < attributes.size(); ++i)
        {
            Object nextItem = attributes.get(i);
            if (nextItem instanceof Expression)
                if (((Expression) nextItem).isContextDependent(ctx))
                    return true;
        }
        return false;
    }

    @Override
    public String toString()
    {
        StringBuilder buf = new StringBuilder(256);

        boolean first = true;
        for (Iterator<Object> iter = this.attributes.iterator(); iter.hasNext();)
        {
            Object element = iter.next();
            if (!first && !(element instanceof ArrayIndexExpression))
                buf.append(".");//$NON-NLS-1$
            first = false;
            buf.append(element);
        }

        return buf.toString();
    }

}
