/**
*
* 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.yoko.rmi.impl;

import org.omg.CORBA.ORB;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.rmi.Remote;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;

import javax.rmi.PortableRemoteObject;

abstract class RemoteDescriptor extends TypeDescriptor {
    private java.util.Map method_map;

    private java.util.Map refl_method_map;

    private MethodDescriptor[] operations;

    private Class[] remote_interfaces;

    protected List super_descriptors;

    @Override
    protected abstract RemoteInterfaceDescriptor genRemoteInterface();

    static final Class REMOTE_CLASS = Remote.class;

    static final Class OBJECT_CLASS = java.lang.Object.class;

    static final java.lang.Class REMOTE_EXCEPTION = java.rmi.RemoteException.class;

    String[] _ids;

    public String[] all_interfaces() {
        if (_ids == null) {
            Class[] ifaces = collect_remote_interfaces(type);
            int len = ifaces.length;
            String[] ids = new String[len];
            for (int i = 0; i < len; i++) {
                TypeDescriptor desc = repo.getDescriptor(ifaces[i]);
                ids[i] = desc.getRepositoryID();
            }

            _ids = ids;
        }

        return _ids;
    }

    public MethodDescriptor getMethod(String idl_name) {
        if (operations == null) {
            init_methods();
        }

        if (method_map == null) {
            method_map = new HashMap();
            for (int i = 0; i < operations.length; i++) {
                method_map.put(operations[i].getIDLName(), operations[i]);
            }
        }

        return (MethodDescriptor) method_map.get(idl_name);
    }

    void debugMethodMap() {
        if (logger.isLoggable(Level.FINER)) {
            logger.finer("METHOD MAP FOR " + type.getName());

            Iterator it = method_map.keySet().iterator();
            while (it.hasNext()) {
                String idl_name = (String) it.next();
                MethodDescriptor desc = (MethodDescriptor) method_map.get(idl_name);
                logger.finer("IDL " + idl_name + " -> "+ desc.reflected_method);
            }
        }
    }

    public MethodDescriptor getMethod(Method refl_method) {
        if (operations == null) {
            init_methods();
        }

        if (refl_method_map == null) {
            refl_method_map = new HashMap();
            for (int i = 0; i < operations.length; i++) {
                refl_method_map.put(operations[i].getReflectedMethod(), operations[i]);
            }
        }

        return (MethodDescriptor) refl_method_map.get(refl_method);
    }

    RemoteDescriptor(Class type, TypeRepository repository) {
        super(type, repository);
    }

    public MethodDescriptor[] getMethods() {
        if (operations == null) {
            init_methods();
        }
        return operations;
    }

    public synchronized void init_methods() {
        if (operations != null) {
            return;
        }

        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                init_methods0();
                return null;
            }
        });
    }

    private void init_methods0() {

        ArrayList method_list = new ArrayList();

        // first step is to build the helpers for any super classes
        Class[] supers = type.getInterfaces();
        super_descriptors = new ArrayList();

        Map all_methods = new HashMap();
        Map lower_case_names = new HashMap();
        for (int i = 0; i < supers.length; i++) {
            Class iface = supers[i];

            if (!REMOTE_CLASS.equals(iface) && !OBJECT_CLASS.equals(iface)
                    && REMOTE_CLASS.isAssignableFrom(iface)
                    && iface.isInterface()) {
                RemoteDescriptor superHelper = (RemoteDescriptor)repo.getDescriptor(iface);

                super_descriptors.add(superHelper);

                MethodDescriptor[] superOps = superHelper.getMethods();
                for (int j = 0; j < superOps.length; j++) {
                    MethodDescriptor op = superOps[j];

                    method_list.add(op);
                    addMethodOverloading(all_methods, op.getReflectedMethod());
                    addMethodCaseSensitive(lower_case_names, op.getReflectedMethod());
                }
            }
        }

        // next, build the method helpers for this class
        Method[] methods = getLocalMethods();

        // register methods
        for (int i = 0; i < methods.length; i++) {
            addMethodOverloading(all_methods, methods[i]);
            addMethodCaseSensitive(lower_case_names, methods[i]);
        }

        Set overloaded_names = new HashSet();
        Iterator it = all_methods.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String mname = (String) entry.getKey();
            Set s = (Set) entry.getValue();
            if (s.size() > 1) {
                overloaded_names.add(mname);
            }
        }

        for (int i = 0; i < methods.length; i++) {
            MethodDescriptor op = new MethodDescriptor(methods[i], repo);

            String mname = op.java_name;

            // is there another method that differs only in case?
            Set same_case_names = (Set) lower_case_names.get(mname.toLowerCase());
            if (same_case_names.size() > 1) {
                op.setCaseSensitive(true);
            }

            // is this method overloaded?
            Set overload_names = (Set) all_methods.get(mname);
            if (overload_names.size() > 1) {
                op.setOverloaded(true);
            }

            op.init();

            method_list.add(op);
        }

        // init method map...
        method_map = new HashMap();
        for (int i = 0; i < method_list.size(); i++) {
            MethodDescriptor desc = (MethodDescriptor) method_list.get(i);
            logger.finer("Adding method " + desc.java_name + " to method map under " + desc.getIDLName());
            method_map.put(desc.getIDLName(), desc);
        }

        //
        // initialize "operations" from the values of the map, such
        // that repeat methods are eliminated.
        //
        operations = (MethodDescriptor[]) method_map.values().toArray(
                new MethodDescriptor[0]);

        debugMethodMap();
    }

    private void addMethodOverloading(Map map, Method m) {
        String mname = m.getName();
        Set entry = (Set) map.get(mname);

        if (entry == null) {
            entry = new HashSet();
            map.put(mname, entry);
        }

        entry.add(createMethodSelector(m));
    }

    Method[] getLocalMethods() {
        ArrayList result = new ArrayList();

        addNonRemoteInterfaceMethods(type, result);

        Method[] out = new Method[result.size()];
        result.toArray(out);
        return out;
    }

    void addNonRemoteInterfaceMethods(Class clz, ArrayList result) {
        Method[] methods;
        try {
            methods = clz.getDeclaredMethods();
        } catch (NoClassDefFoundError e) {
            ClassLoader clzClassLoader = clz.getClassLoader();
            logger.log(Level.FINER, "cannot find class " + e.getMessage() + " from "
                    + clz.getName() + " (classloader " + clzClassLoader + "): "
                    + e.getMessage(), e);
            throw e;
        }
        for (int j = 0; j < methods.length; j++) {
            // since this is a remote interface, we need to add everything
            result.add(methods[j]);
        }

        Class[] ifaces = clz.getInterfaces();
        for (int i = 0; i < ifaces.length; i++) {
            if (!REMOTE_CLASS.isAssignableFrom(ifaces[i])) {
                addNonRemoteInterfaceMethods(ifaces[i], result);
            }
        }
    }

    boolean isRemoteMethod(Method m) {
        Class[] ex = m.getExceptionTypes();

        for (int i = 0; i < ex.length; i++) {
            if (REMOTE_EXCEPTION.isAssignableFrom(ex[i]))
                return true;
        }

        return false;
    }

    private static String createMethodSelector(java.lang.reflect.Method m) {
        StringBuffer sb = new StringBuffer(m.getName());
        sb.append('(');
        Class[] parameterTypes = m.getParameterTypes();
        for (int n = 0; n < parameterTypes.length; n++) {
            sb.append(parameterTypes[n].getName());
            if (n < parameterTypes.length - 1) {
                sb.append(", ");
            }
        }
        sb.append(')');
        return sb.toString().intern();
    }

    private void addMethodCaseSensitive(Map map, Method m) {
        String mname = m.getName();
        String lowname = mname.toLowerCase();
        Set entry = (Set) map.get(lowname);

        if (entry == null) {
            entry = new HashSet();
            map.put(lowname, entry);
        }

        entry.add(mname);
    }

    private void collect_interfaces(Set s, Class c) {
        if (c.isInterface() && !REMOTE_CLASS.equals(c))
            s.add(c);

        Class sup = c.getSuperclass();
        if (sup != null && !OBJECT_CLASS.equals(sup)) {
            collect_interfaces(s, sup);
        }

        Class[] supers = c.getInterfaces();

        for (int i = 0; i < supers.length; i++) {
            Class iface = supers[i];

            if (!REMOTE_CLASS.equals(iface)
                    && REMOTE_CLASS.isAssignableFrom(iface)) {
                collect_interfaces(s, iface);
            }
        }
    }

    protected Class[] collect_remote_interfaces(Class c) {
        if (remote_interfaces != null)
            return remote_interfaces;

        Set s = new TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                Class c1 = (Class) o1;
                Class c2 = (Class) o2;

                if (c1.equals(c2))
                    return 0;

                if (c1.isAssignableFrom(c2)) {
                    // c2 is more specific (so it should come first)

                    return 1;
                } else if (c2.isAssignableFrom(c1)) {
                    // c1 is more specific (so it should come first)

                    return -1;
                } else // they are unrelated
                {
                    // just define some consistent order...
                    return c1.getName().compareTo(c2.getName());
                }
            }
        });

        collect_interfaces(s, c);
        remote_interfaces = new Class[s.size()];
        s.toArray(remote_interfaces);
        return remote_interfaces;
    }

    /** Read an instance of this value from a CDR stream */
    @Override
    public Object read(InputStream in) {
        return PortableRemoteObject.narrow(in.read_Object(),
                type);
    }

    /** Write an instance of this value to a CDR stream */
    @Override
    public void write(OutputStream out, Object val) {
        javax.rmi.CORBA.Util.writeRemoteObject(out, val);
    }

    @Override
    protected final TypeCode genTypeCode() {
        ORB orb = ORB.init();
        return orb.create_interface_tc(getRepositoryID(), type.getName());
    }

    @Override
    void writeMarshalValue(PrintWriter pw, String outName,
            String paramName) {
        pw.print("javax.rmi.CORBA.Util.writeRemoteObject(");
        pw.print(outName);
        pw.print(',');
        pw.print(paramName);
        pw.print(')');
    }

    @Override
    void writeUnmarshalValue(PrintWriter pw, String inName) {
        pw.print('(');
        pw.print(type.getName());
        pw.print(')');
        pw.print(PortableRemoteObject.class.getName());
        pw.print(".narrow(");
        pw.print(inName);
        pw.print('.');
        pw.print("read_Object(),");
        pw.print(type.getName());
        pw.print(".class)");
    }

    static String classNameFromStub(String name) {
        if (name.startsWith("org.omg.stub."))
            name = name.substring("org.omg.stub.".length());

        // strip xx._X_Stub -> xx.X
        int idx = name.lastIndexOf('.');
        if (name.charAt(idx + 1) == '_' && name.endsWith("_Stub")) {
            if (idx == -1) {
                return name.substring(1, name.length() - 5);
            } else {
                return name.substring(0, idx + 1) /* package. */
                        + name.substring(idx + 2, name.length() - 5);
            }
        }

        return null;
    }

    static String stubClassName(Class c) {

        String cname = c.getName();

        String pkgname = null;
        int idx = cname.lastIndexOf('.');
        if (idx == -1) {
            pkgname = "org.omg.stub";
        } else {
            pkgname = "org.omg.stub." + cname.substring(0, idx);
        }

        String cplain = cname.substring(idx + 1);

        return pkgname + "._" + cplain + "_Stub";
    }

    void writeStubClass(PrintWriter pw) {

        Class c = type;
        String cname = c.getName();
        String fullname = stubClassName(c);
        //String stubname = fullname.substring(fullname.lastIndexOf('.') + 1);
        String pkgname = fullname.substring(0, fullname.lastIndexOf('.'));
        String cplain = cname.substring(cname.lastIndexOf('.') + 1);

        pw.println("/** ");
        pw.println(" *  RMI/IIOP stub for " + cname);
        pw.println(" *  Generated using Apache Yoko stub generator.");
        pw.println(" */");

        pw.println("package " + pkgname + ";\n");

        pw.println("public class _" + cplain + "_Stub");
        pw.println("\textends javax.rmi.CORBA.Stub");
        pw.println("\timplements " + cname);
        pw.println("{");

        //
        // construct String[] _ids;
        //
        String[] all_interfaces = all_interfaces();
        pw.println("\tprivate static final String[] _ids = {");
        for (int i = 0; i < all_interfaces.length; i++) {
            pw.println("\t\t\"" + all_interfaces[i] + "\",");
        }
        pw.println("\t};\n");

        pw.println("\tpublic String[] _ids() {");
        pw.println("\t\treturn _ids;");
        pw.println("\t}");

        //
        // now, construct stub methods
        //
        MethodDescriptor[] meths = getMethods();
        for (int i = 0; i < meths.length; i++) {
            meths[i].writeStubMethod(pw);
        }

        pw.println("}");
    }

    String getStubClassName() {
        Class c = type;
        String cname = c.getName();

        String pkgname = null;
        int idx = cname.lastIndexOf('.');
        if (idx == -1) {
            pkgname = "org.omg.stub";
        } else {
            pkgname = "org.omg.stub." + cname.substring(0, idx);
        }

        String cplain = cname.substring(idx + 1);

        return pkgname + "." + "_" + cplain + "_Stub";
    }

    @Override
    void addDependencies(Set classes) {
        Class c = type;

        if (c == Remote.class || classes.contains(c))
            return;

        classes.add(c);

        if (c.getSuperclass() != null) {
            TypeDescriptor desc = repo.getDescriptor(c.getSuperclass());
            desc.addDependencies(classes);
        }

        Class[] ifaces = c.getInterfaces();
        for (int i = 0; i < ifaces.length; i++) {
            TypeDescriptor desc = repo.getDescriptor(ifaces[i]);
            desc.addDependencies(classes);
        }

        MethodDescriptor[] mths = getMethods();
        for (int i = 0; i < mths.length; i++) {
            mths[i].addDependencies(classes);
        }
    }

    @Override
    boolean copyInStub() {
        return false;
    }
}
