/**
 * 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.mrql;

import java.lang.reflect.*;
import org.apache.mrql.gen.*;
import java.util.*;

/** imports external Java methods into MRQL */
final public class ClassImporter {
    final static boolean trace_imported_methods = false;

    final static String[] object_methods
        = { "hashCode", "getClass", "wait", "equals", "toString", "notify", "notifyAll" };

    static Vector<MethodInfo> methods = new Vector<MethodInfo>();

    public static void load_classes () {
        if (methods == null)
            methods = new Vector<MethodInfo>();
        if (methods.size() == 0) {
            importClass("org.apache.mrql.SystemFunctions");
            //****** import your classes with user-defined functions here
        }
    }

    private static boolean object_method ( String s ) {
        for (int i = 0; i < object_methods.length; i++)
            if (object_methods[i].equals(s))
                return true;
        return false;
    }

    private static Tree getType ( Class<?> c, Type[] genTypes ) {
        String cn = c.getCanonicalName();
        Class<?>[] inf = c.getInterfaces();
        if (cn.equals("org.apache.mrql.MRData"))
            return new VariableLeaf("any");
        if (cn.equals("org.apache.mrql.MR_list")) {
            Class ec = ((Class)((ParameterizedType)genTypes[0]).getActualTypeArguments()[0]);
            return new Node("list",new Trees(getType(ec,new Type[0])));
        }
        if (cn.equals("org.apache.mrql.MR_bag")) {
            Class ec = ((Class)((ParameterizedType)genTypes[0]).getActualTypeArguments()[0]);
            return new Node("bag",new Trees(getType(ec,new Type[0])));
        }
        if (cn.startsWith("org.apache.mrql.MR_"))
            return new VariableLeaf(cn.substring(19));
        if (cn.equals("org.apache.mrql.Bag"))
            return new Node("bag",new Trees(new VariableLeaf("any")));
        if (cn.equals("org.apache.mrql.Inv"))
            return new VariableLeaf("any");
        if (cn.equals("org.apache.mrql.Union"))
            return new VariableLeaf("union");
        if (cn.equals("org.apache.mrql.Lambda"))
            return new VariableLeaf("any");
        if (inf.length > 0 && inf[0].equals("org.apache.mrql.MRData"))
            return new VariableLeaf("any");
        throw new Error("Unsupported type in imported method: "+cn);
    }

    private static Trees signature ( Method m ) {
        Class<?> co = m.getReturnType();
        Class<?>[] cs = m.getParameterTypes();
        Type[] gs = m.getGenericParameterTypes();
        Trees as = new Trees(getType(co,new Type[]{m.getGenericReturnType()}));
        for (int i = 0; i < cs.length; i++)
            as = as.append(getType(cs[i],gs));
        return as;
    }

    public static String method_name ( int method_number ) {
        return methods.get(method_number).name;
    }

    public static Trees signature ( int method_number ) {
        return methods.get(method_number).signature;
    }

    /** import all Java methods from a given Java class */
    public static void importClass ( String class_name ) {
        try {
            Method[] ms = Class.forName(class_name).getMethods();
            Vector<MethodInfo> mv = new Vector<MethodInfo>();
            for (int i = 0; i < ms.length; i++)
                if (!object_method(ms[i].getName()) && ms[i].getModifiers() == 9)
                    try {
                        Trees sig = signature(ms[i]);
                        MethodInfo m = new MethodInfo(ms[i].getName(),sig,ms[i]);
                        mv.add(m);
                        methods.add(m);
                    } catch ( Exception e ) {
                        System.out.println("Warning: method "+ms[i].getName()+" cannot be imported");
                        System.out.println(e);
                        throw new Error("");
                    };
            Collections.sort(methods);
            if (Translator.functions == null)
                Translator.functions = Trees.nil;
            for ( MethodInfo m: methods )
                Translator.functions = Translator.functions.append(new Node(m.name,m.signature));
            if (trace_imported_methods) {
                System.out.print("Importing methods: ");
                for (int i = 0; i < mv.size(); i++ )
                    System.out.print(mv.get(i).name+mv.get(i).signature.tail()
                                     +":"+mv.get(i).signature.head()+"  ");
                System.out.println();
            }
        } catch (ClassNotFoundException x) {
            throw new Error("Undefined class: "+class_name);
        }
    }

    /** import a Java method with a given name from a given Java class */
    public static void importMethod ( String class_name, String method_name ) {
        try {
            Method[] ms = Class.forName(class_name).getMethods();
            MethodInfo m = null;
            for (int i = 0; i < ms.length; i++)
                if (ms[i].getName().equals(method_name)
                    && !object_method(ms[i].getName()) && ms[i].getModifiers() == 9) {
                    Trees sig = signature(ms[i]);
                    m = new MethodInfo(ms[i].getName(),sig,ms[i]);
                    Translator.functions = Translator.functions.append(new Node(ms[i].getName(),sig));
                    break;
                };
            if (m == null)
                throw new Error("No such method: "+method_name);
            methods.add(m);
            Collections.sort(methods);
            if (trace_imported_methods)
                System.out.println("Importing method: "+m.name+m.signature.tail()
                                   +":"+m.signature.head()+"  ");
        } catch (ClassNotFoundException x) {
            throw new Error("Undefined class: "+class_name);
        }
    }

    public static void print_methods () {
        for (int i = 0; i < methods.size(); i++ ) {
            MethodInfo m = methods.get(i);
            System.out.print(" "+m.name+":"+m.signature.tail()+"->"+m.signature.head());
        };
    }

    /** return the method specification of a system method with a given name over some expressions;
     * When the method is overloaded, find the most specific (in terms of arg subtyping)
     * @param method_name the given method name
     * @param args the method expressions
     * @return the method specification
     */
    public static Tree find_method ( String method_name, Trees args ) {
        for (int i = 0; i < methods.size(); i++ ) {
            MethodInfo m = methods.get(i);
            if (m.name.equals(method_name) && TypeInference.subtype(args,m.signature.tail()))
                return m.signature.head();
        };
        return null;
    }

    /** return the method number of a system method with a given name over some expressions;
     * When the method is overloaded, find the most specific (in terms of arg subtyping)
     * @param method_name the given method name
     * @param args the method expressions
     * @return the method number
     */
    public static int find_method_number ( String method_name, Trees args ) {
        for (int i = 0; i < methods.size(); i++ ) {
            MethodInfo m = methods.get(i);
            if (m.name.equals(method_name) && TypeInference.subtype(args,m.signature.tail()))
                return i;
        };
        return -1;
    }

    /** call a system method with a given number over MRData
     * @param method_number the method number
     * @param args in input arguments
     * @return the result of invoking this method over the args
     */
    public static MRData call ( int method_number, MRData... args ) {
        if (method_number < 0 || method_number >= methods.size())
            throw new Error("Run-time error (unknown method name)");
        MethodInfo m = methods.get(method_number);
        try {
            return (MRData)m.method.invoke(null,(Object[])args);
        } catch (Exception e) {
            Tuple t = new Tuple(args.length);
            for ( int i = 0; i < args.length; i++ )
                t.set(i,args[i]);
            System.err.println("Run-time error in method call: "+m.name+t+" of type "
                               +m.signature.tail()+"->"+m.signature.head());
            throw new Error(e.toString());
        }
    }
}
