/*
 * 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 freemarker.ext.beans;

import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;

import freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;
import freemarker.template.utility.ClassUtil;

/**
 * A class that will wrap a reflected method call into a
 * {@link freemarker.template.TemplateMethodModel} interface. 
 * It is used by {@link BeanModel} to wrap reflected method calls
 * for non-overloaded methods.
 */
public final class SimpleMethodModel extends SimpleMethod
    implements
    TemplateMethodModelEx,
    TemplateSequenceModel,
    _UnexpectedTypeErrorExplainerTemplateModel {
    private final Object object;
    private final BeansWrapper wrapper;

    /**
     * Creates a model for a specific method on a specific object.
     * @param object the object to call the method on, or {@code null} for a static method.
     * @param method the method that will be invoked.
     * @param argTypes Either pass in {@code Method#getParameterTypes() method.getParameterTypes()} here,
     *          or reuse an earlier result of that call (for speed). Not {@code null}.
     */
    SimpleMethodModel(Object object, Method method, Class[] argTypes, 
            BeansWrapper wrapper) {
        super(method, argTypes);
        this.object = object;
        this.wrapper = wrapper;
    }

    /**
     * Invokes the method, passing it the arguments from the list.
     */
    public Object exec(List arguments)
        throws TemplateModelException {
        try {
            return wrapper.invokeMethod(object, (Method) getMember(), 
                    unwrapArguments(arguments, wrapper));
        } catch (TemplateModelException e) {
            throw e;
        } catch (Exception e) {
            throw _MethodUtil.newInvocationTemplateModelException(object, getMember(), e);
        }
    }
    
    public TemplateModel get(int index) throws TemplateModelException {
        return (TemplateModel) exec(Collections.singletonList(
                new SimpleNumber(Integer.valueOf(index))));
    }

    public int size() throws TemplateModelException {
        throw new TemplateModelException(
                "Getting the number of items or enumerating the items is not supported on this "
                + ClassUtil.getFTLTypeDescription(this) + " value.\n"
                + "("
                + "Hint 1: Maybe you wanted to call this method first and then do something with its return value. "
                + "Hint 2: Getting items by intex possibly works, hence it's a \"+sequence\"."
                + ")");
    }
    
    @Override
    public String toString() {
        return getMember().toString();
    }

    /**
     * Implementation of experimental interface; don't use it, no backward compatibility guarantee!
     */
    public Object[] explainTypeError(Class[] expectedClasses) {
        final Member member = getMember();
        if (!(member instanceof Method)) {
            return null;  // This shouldn't occur
        }
        Method m = (Method) member;
        
        final Class returnType = m.getReturnType();
        if (returnType == null || returnType == void.class || returnType == Void.class) {
            return null;  // Calling it won't help
        }
        
        String mName = m.getName();
        if (mName.startsWith("get") && mName.length() > 3 && Character.isUpperCase(mName.charAt(3))
                && (m.getParameterTypes().length == 0)) {
            return new Object[] {
                    "Maybe using obj.something instead of obj.getSomething will yield the desired value." };
        } else if (mName.startsWith("is") && mName.length() > 2 && Character.isUpperCase(mName.charAt(2))
                && (m.getParameterTypes().length == 0)) {
            return new Object[] {
                    "Maybe using obj.something instead of obj.isSomething will yield the desired value." };
        } else {
            return new Object[] {
                    "Maybe using obj.something(",
                    (m.getParameterTypes().length != 0 ? "params" : ""),
                    ") instead of obj.something will yield the desired value" };
        }
    }
    
}