/**
*
* 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 java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.logging.Logger;
import java.util.logging.Level;

import javax.rmi.CORBA.PortableRemoteObjectDelegate;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.Tie;
import javax.rmi.CORBA.Util;

import org.apache.yoko.rmi.util.ClientUtil;
import org.apache.yoko.rmi.util.GetSystemPropertyAction;
import org.apache.yoko.rmi.util.stub.MethodRef;
import org.apache.yoko.rmi.util.stub.StubClass;
import org.apache.yoko.rmi.util.stub.StubInitializer;
import org.apache.yoko.rmispec.util.UtilLoader;
import org.omg.CORBA.BAD_INV_ORDER;
import org.omg.CORBA.portable.IDLEntity;
import org.omg.CORBA.portable.ObjectImpl;


public class PortableRemoteObjectImpl implements PortableRemoteObjectDelegate {
    static final Logger LOGGER = Logger
            .getLogger(PortableRemoteObjectImpl.class.getName());

    static {
        // Initialize the stub handler factory when first loaded to ensure we have
        // class loading visibility to the factory.
        getRMIStubInitializer();
    }

    static org.omg.CORBA.ORB getORB() {
        return RMIState.current().getORB();
    }

    static org.omg.PortableServer.POA getPOA() {
        return RMIState.current().getPOA();
    }

    static ClassLoader getClassLoader() {
        return RMIState.current().getClassLoader();
    }

    public void connect(Remote target, Remote source)
            throws java.rmi.RemoteException {
        if (!(source instanceof javax.rmi.CORBA.Stub))
            source = toStub(source);

        ObjectImpl obj;
        if (target instanceof ObjectImpl) {
            obj = (ObjectImpl) target;

        } else {

            try {
                exportObject(target);
            } catch (RemoteException ex) {
                // ignore "already exported test" //
            }

            try {
                obj = (ObjectImpl) toStub(target);
            } catch (java.rmi.NoSuchObjectException ex) {
                throw (RemoteException)new RemoteException("cannot convert to stub!").initCause(ex);
            }
        }

        try {
            ((javax.rmi.CORBA.Stub) source).connect(((ObjectImpl) obj)._orb());
        } catch (org.omg.CORBA.BAD_OPERATION bad_operation) {
            throw (RemoteException)new RemoteException(bad_operation.getMessage())
                .initCause(bad_operation);
        }
    }

    private Object narrowRMI(ObjectImpl narrowFrom, Class<?> narrowTo) {
        if (LOGGER.isLoggable(Level.FINE))
            LOGGER.fine(String.format("RMI narrowing %s => %s", narrowFrom.getClass().getName(), narrowTo.getName()));
        ObjectImpl object = narrowFrom;

        final String codebase = getCodebase(narrowFrom);

        RMIState state = RMIState.current();

        javax.rmi.CORBA.Stub stub;
        try {
            stub = createStub(state, codebase, narrowTo);
        } catch (ClassNotFoundException ex) {
            throw (ClassCastException)new ClassCastException(narrowTo.getName()).initCause(ex);
        }

        org.omg.CORBA.portable.Delegate delegate;
        try {
            // let the stub adopt narrowFrom's identity
            delegate = object._get_delegate();

        } catch (org.omg.CORBA.BAD_OPERATION ex) {
            // ignore
            delegate = null;
        }

        stub._set_delegate(delegate);

        return stub;
    }

    private String getCodebase(ObjectImpl narrowFrom) {
        String codebase;
        if (narrowFrom instanceof org.omg.CORBA_2_3.portable.ObjectImpl) {
            org.omg.CORBA_2_3.portable.ObjectImpl object_2_3 = (org.omg.CORBA_2_3.portable.ObjectImpl) narrowFrom;

            try {
                codebase = object_2_3._get_codebase();
            } catch (org.omg.CORBA.BAD_OPERATION ex) {
                codebase = null;
            }
        } else {
            codebase = null;
        }
        return codebase;
    }

    private Object narrowIDL(ObjectImpl narrowFrom, Class<?> narrowTo) {
        if (LOGGER.isLoggable(Level.FINE))
            LOGGER.fine(String.format("IDL narrowing %s => %s", narrowFrom.getClass().getName(), narrowTo.getName()));
        final ClassLoader idlClassLoader = UtilImpl.getClassLoader(narrowTo);
        final String codebase = getCodebase(narrowFrom);
        final String helperClassName = narrowTo.getName() + "Helper";

        try {
            final Class<?> helperClass = Util.loadClass(helperClassName, codebase, idlClassLoader);
            final Method helperNarrow = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
                @Override
                public Method run() throws Exception {
                    return helperClass.getMethod("narrow", org.omg.CORBA.Object.class);
                }
            });
            return helperNarrow.invoke(null, narrowFrom);
        } catch (PrivilegedActionException e) {
            throw (ClassCastException)new ClassCastException(narrowTo.getName()).initCause(e.getCause());
        } catch (Exception e) {
            throw (ClassCastException)new ClassCastException(narrowTo.getName()).initCause(e);
        }
    }

    public Object narrow(Object narrowFrom, @SuppressWarnings("rawtypes") Class narrowTo)
            throws ClassCastException {
        if (narrowFrom == null)
            return null;

        if (narrowTo.isInstance(narrowFrom))
            return narrowFrom;

        final String fromClassName = narrowFrom.getClass().getName();
        final String toClassName = narrowTo.getName();
        if (LOGGER.isLoggable(Level.FINE))
            LOGGER.finer(String.format("narrow %s => %s", fromClassName, toClassName));

        if (!(narrowFrom instanceof org.omg.CORBA.portable.ObjectImpl))
            throw new ClassCastException(String.format(
                    "object to narrow (runtime type %s) is not an instance of %s",
                    fromClassName, ObjectImpl.class.getName()));
        if (!narrowTo.isInterface())
            throw new ClassCastException(String.format("%s is not an interface", toClassName));

        final boolean isRemote = Remote.class.isAssignableFrom(narrowTo);
        final boolean isIDLEntity = IDLEntity.class.isAssignableFrom(narrowTo);

        if (isRemote && isIDLEntity)
            throw new ClassCastException(String.format(
                    "%s invalidly extends both %s and %s",
                    toClassName, Remote.class.getName(), IDLEntity.class.getName()));
        if (isRemote)
            return narrowRMI((ObjectImpl) narrowFrom, narrowTo);
        if (isIDLEntity)
            return narrowIDL((ObjectImpl) narrowFrom, narrowTo);

        throw new ClassCastException(String.format(
                    "%s extends neither %s nor %s",
                    toClassName, Remote.class.getName(), IDLEntity.class.getName()));
    }

    static java.rmi.Remote narrow1(RMIState state, ObjectImpl object, Class<?> narrowTo) throws ClassCastException {
        Stub stub;

        try {
            stub = createStub(state, null, narrowTo);
        } catch (ClassNotFoundException ex) {
            throw (ClassCastException)new ClassCastException(narrowTo.getName()).initCause(ex);
        }

        org.omg.CORBA.portable.Delegate delegate;
        try {
            // let the stub adopt narrowFrom's identity
            delegate = object._get_delegate();

        } catch (org.omg.CORBA.BAD_OPERATION ex) {
            // ignore
            delegate = null;
        }

        stub._set_delegate(delegate);

        return (java.rmi.Remote) stub;
    }

    static private Stub createStub(RMIState state, String codebase, Class<?> type) throws ClassNotFoundException {
        if (Remote.class == type) {
            return new RMIRemoteStub();
        }

        if (ClientUtil.isRunningAsClientContainer()) {
            Stub stub = state.getStaticStub(codebase, type);
            if (stub != null) {
                return stub;
            }
        }

        return createRMIStub(state, type);
    }

    static Object[] NO_ARG = new Object[0];

    static Stub createRMIStub(RMIState state, Class<?> type) throws ClassNotFoundException {
        if (!type.isInterface()) {
            throw new RuntimeException("non-interfaces not supported");
        }

        LOGGER.fine("Creating RMI stub for class " + type.getName());

        Constructor<? extends Stub> cons = getRMIStubClassConstructor(state, type);

        try {
            Stub result = cons.newInstance(NO_ARG);
            return result;
        } catch (InstantiationException ex) {
            throw new RuntimeException(
                    "internal problem: cannot instantiate stub", ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException(
                    "internal problem: cannot instantiate stub", ex.getCause());
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(
                    "internal problem: cannot instantiate stub", ex);
        }
    }

    private static java.lang.reflect.Method stub_write_replace;

    static {
        try {
            stub_write_replace = RMIStub.class.getDeclaredMethod(
                    "writeReplace", new Class[0]);

        } catch (Throwable ex) {
            LOGGER.log(Level.WARNING, "cannot initialize: \n" + ex.getMessage(), ex);
            throw new Error("cannot initialize", ex);
        }
    }

    static synchronized Class<?> getRMIStubClass(RMIState state, Class<?> type) throws ClassNotFoundException {
        return getRMIStubClassConstructor(state, type).getDeclaringClass();
    }

    static Constructor<? extends Stub> getRMIStubClassConstructor(RMIState state, Class<?> type) throws ClassNotFoundException {
        LOGGER.fine("Requesting stub constructor of class " + type.getName());
        @SuppressWarnings("unchecked")
        Constructor<? extends Stub> cons = (Constructor<? extends Stub>) state.stub_map.get(type);

        if (cons != null) {
            LOGGER.fine("Returning cached constructor of class " + cons.getDeclaringClass().getName());
            return cons;
        }

        TypeRepository repository = state.getTypeRepository();
        RemoteDescriptor desc = (RemoteDescriptor) repository.getRemoteDescriptor(type);

        MethodDescriptor[] mdesc = desc.getMethods();
        MethodDescriptor[] descriptors = new MethodDescriptor[mdesc.length + 1];
        for (int i = 0; i < mdesc.length; i++) {
            descriptors[i] = mdesc[i];
        }

        LOGGER.finer("TYPE ----> " + type);
        LOGGER.finer("LOADER --> " + UtilImpl.getClassLoader(type));
        LOGGER.finer("CONTEXT -> " + getClassLoader());

        MethodRef[] methods = new MethodRef[descriptors.length];

        for (int i = 0; i < mdesc.length; i++) {
            Method m = descriptors[i].getReflectedMethod();
            LOGGER.finer("Method ----> " + m);
            methods[i] = new MethodRef(m);
        }
        methods[mdesc.length] = new MethodRef(stub_write_replace);


        Class<?> clazz = null;

        try {
            /* Construct class! */
            clazz = StubClass.make(/* the class loader to use */
            UtilImpl.getClassLoader(type),

            /* the bean developer's bean class */
            RMIStub.class,

            /* interfaces */
            new Class[] { type },

            /* the methods */
            methods,

            /* contains only ejbCreate */
            null,

            /* our data objects */
            descriptors,

            /* the handler method */
            getPOAStubInvokeMethod(),

            /* package name (use superclass') */
            getPackageName(type),

            /* provider of handlers */
            getRMIStubInitializer());
        } catch (java.lang.NoClassDefFoundError ex) {
            /* Construct class! */
            clazz = StubClass.make(/* the class loader to use */
            getClassLoader(),

            /* the bean developer's bean class */
            RMIStub.class,

            /* interfaces */
            new Class[] { type },

            /* the methods */
            methods,

            /* contains only ejbCreate */
            null,

            /* our data objects */
            descriptors,

            /* the handler method */
            getPOAStubInvokeMethod(),

            /* package name (use superclass') */
            getPackageName(type),

            /* provider of handlers */
            getRMIStubInitializer());

        }

        if (clazz != null) {
            try {
                cons = (Constructor<? extends Stub>) clazz.getConstructor();
                state.stub_map.put(type, cons);
            } catch (NoSuchMethodException e) {
                LOGGER.log(Level.FINER, "constructed stub has no default constructor", e);
            }
        }

        return cons;
    }

    static String getPackageName(Class clazz) {
        String class_name = clazz.getName();
        int idx = class_name.lastIndexOf('.');
        if (idx == -1) {
            return null;
        } else {
            return class_name.substring(0, idx);
        }
    }

    private static Method poa_stub_invoke_method;

    static Method getPOAStubInvokeMethod() {
        if (poa_stub_invoke_method == null) {

            // NYI: PrivilegedAction
            try {
                // get the interface method used to invoke the stub handler
                poa_stub_invoke_method = (StubHandler.class)
                        .getDeclaredMethod("invoke", new Class[] {
                                RMIStub.class, MethodDescriptor.class,
                                Object[].class });
            } catch (NoSuchMethodException ex) {
                throw new Error("cannot find RMI Stub handler invoke method", ex);
            }

        }

        return poa_stub_invoke_method;

    }

    public java.rmi.Remote toStub(java.rmi.Remote value)
            throws java.rmi.NoSuchObjectException {
        if (value instanceof javax.rmi.CORBA.Stub)
            return value;

        javax.rmi.CORBA.Tie tie = javax.rmi.CORBA.Util.getTie(value);
        if (tie == null) {
            throw new java.rmi.NoSuchObjectException("object not exported");
        }

        RMIServant servant = (RMIServant) tie;

        try {
            org.omg.PortableServer.POA poa = servant.getRMIState().getPOA();
            org.omg.CORBA.Object ref = poa.servant_to_reference(servant);
            return (java.rmi.Remote) narrow(ref, servant.getJavaClass());
        } catch (org.omg.PortableServer.POAPackage.ServantNotActive ex) {
            throw new RuntimeException("internal error: " + ex.getMessage(), ex);
        } catch (org.omg.PortableServer.POAPackage.WrongPolicy ex) {
            throw new RuntimeException("internal error: " + ex.getMessage(), ex);
        }
    }

    public void exportObject(Remote obj) throws java.rmi.RemoteException {
        RMIState state = RMIState.current();

        try {
            state.checkShutDown();
        } catch (BAD_INV_ORDER ex) {
            throw new RemoteException("RMIState is deactivated", ex);
        }

        Tie tie = javax.rmi.CORBA.Util.getTie(obj);

        if (tie != null)
            throw new java.rmi.RemoteException("object already exported");

        RMIServant servant = new RMIServant(state);
        javax.rmi.CORBA.Util.registerTarget(servant, obj);

        LOGGER.finer("exporting instance of " + obj.getClass().getName()
                + " in " + state.getName());

        try {
            servant._id = state.getPOA().activate_object(servant);
        } catch (org.omg.PortableServer.POAPackage.ServantAlreadyActive ex) {
            throw new java.rmi.RemoteException("internal error: " + ex.getMessage(), ex);
        } catch (org.omg.PortableServer.POAPackage.WrongPolicy ex) {
            throw new java.rmi.RemoteException("internal error: " + ex.getMessage(), ex);
        }
    }

    public void unexportObject(Remote obj)
            throws java.rmi.NoSuchObjectException {
        javax.rmi.CORBA.Util.unexportObject(obj);
    }

    // the factory object used for creating stub initializers
    static private StubInitializer initializer = null;
    // the default stub handler, which is ours without overrides.
    private static final String defaultInitializer = "org.apache.yoko.rmi.impl.RMIStubInitializer";

    /**
     * Get the RMI stub handler initializer to use for RMI invocation
     * stubs.  The Class in question must implement the StubInitializer method.
     *
     * @return The class used to create StubHandler instances.
     */
    private static StubInitializer getRMIStubInitializer() {
        if (initializer == null) {
            String factory = (String)AccessController.doPrivileged(new GetSystemPropertyAction("org.apache.yoko.rmi.RMIStubInitializerClass", defaultInitializer));
            try {
                initializer = (StubInitializer)(UtilLoader.loadServiceClass(factory, "org.apache.yoko.rmi.RMIStubInitializerClass").newInstance());
            } catch (Exception e) {
                throw (org.omg.CORBA.INITIALIZE)new org.omg.CORBA.INITIALIZE(
                    "Can not create RMIStubInitializer: " + factory).initCause(e);
            }
        }
        return initializer;
    }
}
