/**
 *
 * 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.MARSHAL;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.ObjectImpl;
import org.omg.CORBA.portable.OutputStream;

import javax.rmi.CORBA.Util;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map;

class IDLEntityDescriptor extends ValueDescriptor {
    private final boolean isCorba;
    private final Class helperType;

    IDLEntityDescriptor(Class type, TypeRepository repository) {
        super(type, repository);

        isCorba = org.omg.CORBA.Object.class.isAssignableFrom(type);
        try {
            final String helperName = type.getName() + "Helper";
            helperType = Util.loadClass(helperName, null, type.getClassLoader());
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("cannot load IDL Helper class for "
                    + type, ex);
        }
    }

    @Override
    protected final String genIDLName() {
        return "org_omg_boxedIDL_" + super.genIDLName();
    }

    private volatile Method readMethod = null;
    private Method getReadMethod() {
        if (null == readMethod) readMethod = genHelperMethod("write");
        return readMethod;
    }

    private volatile Method writeMethod = null;
    private Method getWriteMethod() {
        if (null == writeMethod) writeMethod = genHelperMethod("write");
        return writeMethod;
    }

    private volatile Method typeMethod = null;
    private Method getTypeMethod() {
        if (null == typeMethod) typeMethod = genHelperMethod("type");
        return typeMethod;
    }

    private Method genHelperMethod(final String name) {
        return AccessController.doPrivileged(new PrivilegedAction<Method>() {
            @Override
            public Method run() {
                for (Method m: helperType.getDeclaredMethods()) {
                    if (m.getName().equals(name)) return m;
                }
                throw new RuntimeException("Unable to find " + name + " method for " + helperType.getName());
            }
        });
    }

    /** Read an instance of this value from a CDR stream */
    @Override
    public Object read(InputStream in) {
        org.omg.CORBA_2_3.portable.InputStream _in = (org.omg.CORBA_2_3.portable.InputStream) in;
        
        // there are two ways we need to deal with IDLEntity classes.  Ones that also implement 
        // the CORBA Object interface are actual corba objects, and must be handled that way. 
        // Other IDLEntity classes are just transmitted by value. 
        if (isCorba) {
            return _in.read_Object(type);
        } else {
            // we directly call read_value() on the stream here, with the explicitly specified
            // repository ID.  The input stream will handle validating the value tag for us, and eventually
            // will call our readValue() method to deserialize the object.
            return _in.read_value(getRepositoryID());
        }
    }

    @Override
    public Serializable readValue(final InputStream in, final Map offsetMap, final Integer offset) {
        try {
            Serializable value = (Serializable) getReadMethod().invoke(null, new Object[]{in});
            offsetMap.put(offset, value);
            return value;
        } catch (InvocationTargetException ex) {
            throw (MARSHAL)new MARSHAL(""+ex.getCause()).initCause(ex.getCause());
        } catch (IllegalAccessException ex) {
            throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
        }
    }

    /** Write an instance of this value to a CDR stream */
    @Override
    public void write(OutputStream out, Object val) {
        org.omg.CORBA_2_3.portable.OutputStream _out = (org.omg.CORBA_2_3.portable.OutputStream) out;

        
        // there are two ways we need to deal with IDLEntity classes.  Ones that also implement 
        // the CORBA Object interface are actual corba objects, and must be handled that way. 
        // Other IDLEntity classes are just transmitted by value. 
        if (val instanceof ObjectImpl) {
            _out.write_Object((org.omg.CORBA.Object)val); 
        } else {
            // we directly call write_value() on the stream here, with the explicitly specified
            // repository ID.  the output stream will handle writing the value tag for us, and eventually
            // will call our writeValue() method to serialize the object.
            _out.write_value((Serializable)val, getRepositoryID());
        }
    }

    @Override
    public void writeValue(OutputStream out, Serializable val) {
        try {
            getWriteMethod().invoke(null, new Object[] { out, val });
        } catch (InvocationTargetException ex) {
            throw (MARSHAL)new MARSHAL(""+ ex.getCause()).initCause(ex.getCause());
        } catch (IllegalAccessException ex) {
            throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
        }
    }

    @Override
    protected TypeCode genTypeCode() {
        try {
            return (TypeCode) getTypeMethod().invoke(null, new Object[0]);
        } catch (InvocationTargetException ex) {
            throw (MARSHAL)new MARSHAL(""+ex.getCause()).initCause(ex.getCause());
        } catch (IllegalAccessException ex) {
            throw (MARSHAL)new MARSHAL(ex.getMessage()).initCause(ex);
        }
    }
}
