/*
 *  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.codehaus.groovy.runtime;

import groovy.lang.MetaMethod;
import groovy.lang.MetaProperty;
import org.codehaus.groovy.reflection.CachedClass;
import org.codehaus.groovy.reflection.ClassInfo;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * Utility class for MissingMethodException, MissingPropertyException etc.
 * This class contains methods assisting in ranking and listing probable intended
 * methods/fields when a exception is thrown.
 */
public class MethodRankHelper{
    //These are the costs for the various edit operations
    //they are used by the two DamerauLevenshtein implementations
    public static final int DL_SUBSTITUTION = 10;
    public static final int DL_DELETE = 10; //This is also the cost for a insert
    public static final int DL_TRANSPOSITION = 5;
    public static final int DL_CASE = 5;
    
    public static final int MAX_RECOMENDATIONS = 5;
    public static final int MAX_METHOD_SCORE = 50;
    public static final int MAX_CONSTRUCTOR_SCORE = 20;
    public static final int MAX_FIELD_SCORE = 30;
    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];

    private static final class Pair<U,V> {
        private final U u;
        private final V v;
        public Pair(U u, V v){
            this.u = u;
            this.v = v;
        }
    }
    
    /**
     * Returns a string detailing possible solutions to a missing method
     * if no good solutions can be found a empty string is returned.
     *
     * @param methodName the name of the method that doesn't exist
     * @param type the class on which the method is invoked
     * @param arguments the arguments passed to the method
     * @return a string with probable solutions to the exception
     */
    public static String getMethodSuggestionString(String methodName, Class type, Object[] arguments){
        ClassInfo ci = ClassInfo.getClassInfo(type);
        List<MetaMethod> methods = new ArrayList<MetaMethod>(ci.getMetaClass().getMethods());
        methods.addAll(ci.getMetaClass().getMetaMethods());
        List<MetaMethod> sugg = rankMethods(methodName,arguments,methods);
        StringBuilder sb = new StringBuilder();
        if (!sugg.isEmpty()){
            sb.append("\nPossible solutions: ");
            for(int i = 0; i < sugg.size(); i++) {
                if(i != 0) sb.append(", ");
                sb.append(sugg.get(i).getName()).append("(");
                sb.append(listParameterNames(sugg.get(i).getParameterTypes()));
                sb.append(")");
            }
        }
        Class[] argumentClasses = getArgumentClasses(arguments);
        List<Pair<Class,Class>> conflictClasses = getConflictClasses(sugg,argumentClasses);
        if (!conflictClasses.isEmpty()){
            sb.append("\nThe following classes appear as argument class and as parameter class, ");
            sb.append("but are defined by different class loader:\n");
            boolean first = true;
            for(Pair<Class,Class> pair: conflictClasses) {
                if (!first) {
                    sb.append(", ");
                } else {
                    first = false;
                }
                sb.append(pair.u.getName()).append(" (defined by '");
                sb.append(pair.u.getClassLoader());
                sb.append("' and '");
                sb.append(pair.v.getClassLoader());
                sb.append("')");
            }
            sb.append("\nIf one of the method suggestions matches the method you wanted to call, ");
            sb.append("\nthen check your class loader setup.");
        }
        return sb.toString();
    }
    
    private static List<Pair<Class,Class>> getConflictClasses(List<MetaMethod> sugg, Class[] argumentClasses) {
        List<Pair<Class,Class>> ret = new LinkedList<Pair<Class,Class>>();
        Set<Class> recordedClasses = new HashSet<Class>();
        for (MetaMethod method : sugg) {
            Class[] para = method.getNativeParameterTypes();
            for (Class aPara : para) {
                if (recordedClasses.contains(aPara)) continue;
                for (Class argumentClass : argumentClasses) {
                    if (argumentClass == null) continue;
                    if (argumentClass == aPara) continue;
                    if (argumentClass.getName().equals(aPara.getName())) {
                        ret.add(new Pair<Class, Class>(argumentClass, aPara));
                    }
                }
                recordedClasses.add(aPara);
            }
        }
        return ret;
    }

    private static Class[] getArgumentClasses(Object[] arguments) {
        Class[] argumentClasses = new Class[arguments.length];
        for (int i=0; i<argumentClasses.length; i++) {
            Object arg = arguments[i];
            if (arg==null) continue;
            argumentClasses[i] = arg.getClass();
        }
        return argumentClasses;
    }

    /**
     * Returns a string detailing possible solutions to a missing constructor
     * if no good solutions can be found a empty string is returned.
     *
     * @param arguments the arguments passed to the constructor
     * @param type the class on which the constructor is invoked
     * @return a string with probable solutions to the exception
     */
    public static String getConstructorSuggestionString(Class type, Object[] arguments){
        Constructor[] sugg = rankConstructors(arguments, type.getConstructors());
        if(sugg.length >0){
            StringBuilder sb = new StringBuilder();
            sb.append("\nPossible solutions: ");
            for(int i = 0; i < sugg.length; i++){
                if(i != 0) sb.append(", ");
                sb.append(type.getName()).append("(");
                sb.append(listParameterNames(sugg[i].getParameterTypes()));
                sb.append(")");
            }
            return sb.toString();
        } else{
            return "";
        }
    }
    
    /**
     * Returns a string detailing possible solutions to a missing field or property
     * if no good solutions can be found a empty string is returned.
     *
     * @param fieldName the missing field
     * @param type the class on which the field is sought
     * @return a string with probable solutions to the exception
     */
    public static String getPropertySuggestionString(String fieldName, Class type){
        ClassInfo ci = ClassInfo.getClassInfo(type);
        List<MetaProperty>  fi = ci.getMetaClass().getProperties();
        List<RankableField> rf = new ArrayList<RankableField>(fi.size());
        StringBuilder sb = new StringBuilder();
        sb.append("\nPossible solutions: ");
        
        for(MetaProperty mp : fi) rf.add(new RankableField(fieldName, mp));
        Collections.sort(rf);

        int i = 0;
        for (RankableField f : rf) {
            if (i > MAX_RECOMENDATIONS) break;
            if (f.score > MAX_FIELD_SCORE) break;
            if(i > 0) sb.append(", ");
            sb.append(f.f.getName());
            i++;
        }
        return i > 0? sb.toString(): "";
    }
    
    /**
     * creates a comma separated list of each of the class names.
     *
     * @param cachedClasses the array of Classes
     * @return the Class names
     */
    private static String listParameterNames(Class[] cachedClasses){
        StringBuilder sb = new StringBuilder();
      for(int i =0; i < cachedClasses.length;i++){
          if(i != 0) sb.append(", ");
          sb.append(cachedClasses[i].getName());
      }
      return sb.toString();
    }
    
    
    private static String listParameterNames(CachedClass[] cachedClasses){
        StringBuilder sb = new StringBuilder();
        for(int i =0; i < cachedClasses.length;i++){
            if(i != 0) sb.append(", ");
            sb.append(cachedClasses[i].getName());
        }
        return sb.toString();
      }
    
    /**
     * Returns a sorted(ranked) list of a selection of the methods among candidates which
     * most closely resembles original.
     *
     * @param name
     * @param original
     * @param methods
     * @return a sorted lists of Methods
     */
    private static List<MetaMethod> rankMethods(String name, Object[] original, List<MetaMethod> methods) {
        List<RankableMethod> rm = new ArrayList<RankableMethod>(methods.size());
        if (original==null) original = EMPTY_OBJECT_ARRAY;
        Class[] ta = new Class[original.length];
    
        Class nullC =  NullObject.class;
        for(int i = 0; i < original.length; i++){
            //All nulls have to be wrapped so that they can be compared
            ta[i] = original[i] == null?nullC: original[i].getClass();
        }

        for (MetaMethod m:methods) {
            rm.add(new RankableMethod(name, ta, m));
        }
        Collections.sort(rm);
        
        List<MetaMethod> l =  new ArrayList<MetaMethod>(rm.size());
        for (RankableMethod m : rm) {
            if (l.size() > MAX_RECOMENDATIONS) break;
            if (m.score > MAX_METHOD_SCORE) break;
            l.add(m.m);
        }
        return l;
    }

    /**
     * This class wraps a method object and a score variable so methods 
     * Can easily be ranked by their likeness to a another method
     *
     */
    private static final class RankableMethod implements Comparable {
        final MetaMethod m;
        final Integer score;

        public RankableMethod(String name, Class[] argumentTypes, MetaMethod m2) {
            this.m = m2;
            int nameDist = delDistance(name, m2.getName());

            //unbox primitives
            Class[] mArgs = new Class[m2.getParameterTypes().length];
            for(int i =0; i < mArgs.length; i++){
                //All args have to be boxed since argumentTypes is always boxed
                mArgs[i] = boxVar(m2.getParameterTypes()[i].getTheClass());
            }
            int argDist = damerauLevenshteinDistance(argumentTypes,mArgs);
            this.score = nameDist + argDist;
        }

        public int compareTo(Object o) {
            RankableMethod mo = (RankableMethod) o;
            return score.compareTo(mo.score);
        }
    }

    /**
     * Returns a sorted(ranked) list of a selection of the constructors among candidates which
     * most closely resembles original.
     *
     * @param original
     * @param candidates
     * @return a sorted lists of Methods
     */
    private static Constructor[] rankConstructors(Object[] original, Constructor[] candidates) {
        RankableConstructor[] rc = new RankableConstructor[candidates.length];
        Class[] ta = new Class[original.length];

        Class nullC = NullObject.class;
        for (int i = 0; i < original.length; i++) {
            //All nulls have to be wrapped so that they can be compared
            ta[i] = original[i] == null ? nullC : original[i].getClass();
        }

        for (int i = 0; i < candidates.length; i++) {
            rc[i] = new RankableConstructor(ta, candidates[i]);
        }
        Arrays.sort(rc);
        List<Constructor> l = new ArrayList<Constructor>();
        int index = 0;
        while (l.size() < MAX_RECOMENDATIONS && index < rc.length && rc[index].score < MAX_CONSTRUCTOR_SCORE) {
            l.add(rc[index].c);
            index++;
        }
        return l.toArray(new Constructor[0]);
    }

    /**
     * This class wraps a method object and a score variable so methods 
     * Can easily be ranked by their likeness to a another method
     *
     */
    private static final class RankableConstructor implements Comparable {
        final Constructor c;
        final Integer score;

        public RankableConstructor(Class[] argumentTypes, Constructor c) {
            this.c = c;
            //unbox primitives
            Class[] cArgs = new Class[c.getParameterTypes().length];
            for(int i =0; i < cArgs.length; i++){
                //All args have to be boxed since argumentTypes is always boxed
                cArgs[i] = boxVar(c.getParameterTypes()[i]);
            }

            this.score = damerauLevenshteinDistance(argumentTypes,cArgs);
        }

        public int compareTo(Object o) {
            RankableConstructor co = (RankableConstructor) o;
            return score.compareTo(co.score);
        }
    }
    
    /**
     * This class wraps a method object and a score variable so methods 
     * Can easily be ranked by their likeness to a another method
     *
     */
    private static final class RankableField implements Comparable {
        final MetaProperty f;
        final Integer score;

        public RankableField(String name, MetaProperty mp) {
            this.f = mp;
            this.score = delDistance(name,mp.getName());
        }

        public int compareTo(Object o) {
            RankableField co = (RankableField) o;
            return score.compareTo(co.score);
        }
    }
    
    /**
     * If c is a primitive class this method returns a boxed version
     * otherwise c is returned.
     * In java 1.5 this can be simplified thanks to the Type class.
     * @param c
     * @return a boxed version of c if c can be boxed, else c
     */
    protected static Class boxVar(Class c){
        if(Boolean.TYPE.equals(c)){
            return Boolean.class;
        }else if(Character.TYPE.equals(c)){
            return Character.class;
        }else if(Byte.TYPE.equals(c)){
            return Byte.class;
        }else if(Double.TYPE.equals(c)){
            return Double.class;
        }else if(Float.TYPE.equals(c)){
            return Float.class;
        }else if(Integer.TYPE.equals(c)){
            return Integer.class;
        }else if(Long.TYPE.equals(c)){
            return Long.class;
        }else if(Short.TYPE.equals(c)){
            return Short.class;
        }else{
            return c;
        }
    }
    
    /**
     * This is a small wrapper for nulls
     */
    private static class NullObject{
    }

    /**
     * This is a slightly modified version of the Damerau Levenshtein distance
     * algorithm. It has a additional test to see if a character has switched case,
     * in the original algorithm this counts as a substitution.
     * The "cost" for a substitution is given as 10 instead of 1 in this version,
     * this enables transpositions and case modifications to have a lower cost than
     * substitutions.
     *
     * Currently the lowercase versions of t_j and s_i isn't cached, its probable
     * that some speed could be gained from this.
     * 
     * This version is based on Chas Emerick's implementation of Levenshtein Distance
     * for jakarta commons.
     * @param s a CharSequence
     * @param t the CharSequence to be compared to s
     * @return a value representing the edit distance between s and t
     */
    public static int delDistance(CharSequence s, CharSequence t) {
        if (s == null || t == null) {
            throw new IllegalArgumentException("Strings must not be null");
        }

        int n = s.length(); // length of s
        int m = t.length(); // length of t

        if (n == 0) {
            return m;
        } else if (m == 0) {
            return n;
        }

        //we have to keep 3 rows instead of the 2 used in Levenshtein
        int[][] vals = new int[3][n + 1];


        int _d[]; //placeholder to assist in rotating vals

        // indexes into strings s and t
        int i; // iterates through s
        int j; // iterates through t

        char t_j; // jth character of t
        char s_i; // ith character of s
        int cost; // cost

        for (i = 0; i <= n; i++) {
            vals[1][i] = i * DL_DELETE;
        }

        for (j = 1; j <= m; j++) {
            t_j = t.charAt(j - 1);
            vals[0][0] = j * DL_DELETE;

            for (i = 1; i <= n; i++) {
                s_i = s.charAt(i - 1);
                if (Character.isLowerCase(s_i) ^ Character.isLowerCase(t_j)) {
                    //if s_i and t_i don't have have the same case
                    cost = caselessCompare(s_i, t_j) ? DL_CASE : DL_SUBSTITUTION;
                } else {
                    //if they share case check for substitution
                    cost = s_i == t_j ? 0 : DL_SUBSTITUTION;
                }

                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
                vals[0][i] = Math.min(Math.min(vals[0][i - 1] + DL_DELETE, vals[1][i] + DL_DELETE), vals[1][i - 1] + cost);

                //Check for transposition, somewhat more complex now since we have to check for case
                if (i > 1 && j > 1) {
                    cost = Character.isLowerCase(s_i) ^ Character.isLowerCase(t.charAt(j - 2)) ? DL_CASE : 0;
                    cost = Character.isLowerCase(s.charAt(i - 2)) ^ Character.isLowerCase(t_j) ? cost + DL_CASE : cost;

                    if (caselessCompare(s_i, t.charAt(j - 2)) && caselessCompare(s.charAt(i - 2), t_j)) {
                        vals[0][i] = Math.min(vals[0][i], vals[2][i - 2] + DL_TRANSPOSITION + cost);
                    }
                }
            }

            // rotate all value arrays upwards(older rows get a higher index)
            _d = vals[2];
            vals[2] = vals[1];
            vals[1] = vals[0];
            vals[0] = _d;
        }

        // our last action in the above loop was to rotate vals, so vals[1] now
        // actually has the most recent cost counts
        return vals[1][n];
    }

    /**
     * Compares two characters whilst ignoring case.
     * @param a the first character
     * @param b the second character
     * @return true if the characters are equal
     */
    private static boolean caselessCompare(char a, char b){
        return Character.toLowerCase(a) == Character.toLowerCase(b);
    }
    
    /**
     * This is a implementation of DL distance between two Object arrays instead
     * of character streams. The objects are compared using their equals method.
     * No objects may be null.
     * This implementation is based on Chas Emerick's implementation of Levenshtein Distance
     * for jakarta commons.
     * @param s an Object array
     * @param t this array is compared to s
     * @return the edit distance between the two arrays
     */
    public static int damerauLevenshteinDistance(Object[] s, Object[] t) {
        if (s == null || t == null) {
            throw new IllegalArgumentException("Arrays must not be null");
        }

        int n = s.length; // length of s
        int m = t.length; // length of t

        if (n == 0) {
            return m;
        } else if (m == 0) {
            return n;
        }

        int[][] vals = new int[3][n + 1];


        int _d[]; //placeholder to assist in rotating vals

        // indexes into arrays s and t
        int i; // iterates through s
        int j; // iterates through t

        Object t_j; // jth object of t

        int cost; // cost

        for (i = 0; i <= n; i++) {
            vals[1][i] = i * DL_DELETE ;
        }

        for (j = 1; j <= m; j++) {
            t_j = t[j - 1];
            vals[0][0] = j * DL_DELETE ;

            for (i = 1; i <= n; i++) {
                cost = s[i - 1].equals(t_j)? 0 : DL_SUBSTITUTION;
                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
                vals[0][i] = Math.min(Math.min(vals[0][i - 1] + DL_DELETE, vals[1][i] + DL_DELETE), vals[1][i - 1] + cost);

                //Check for transposition
                if(i > 1 && j > 1 && s[i -1].equals(t[j -2]) && s[i- 2].equals(t_j)){
                    vals[0][i] = Math.min(vals[0][i], vals[2][i-2] + DL_TRANSPOSITION);
                }
            }

            // rotate all value arrays upwards(older rows get a higher index)
            _d = vals[2];
            vals[2] = vals[1];
            vals[1] = vals[0];
            vals[0] = _d;
        }

        return vals[1][n];
    }
}
