/*
 * 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.ode.jacob.vpu;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.apache.ode.jacob.oo.Channel;
import org.apache.ode.jacob.oo.ChannelProxy;
import org.apache.ode.jacob.soup.CommChannel;

public class ChannelFactory {
    private static final Method METHOD_OBJECT_EQUALS;

    static {
        try {
            METHOD_OBJECT_EQUALS = Object.class.getMethod("equals", new Class[] { Object.class });
        } catch (Exception e) {
            throw new AssertionError("No equals(Object) method on Object!");
        }
    }

    public static Object getBackend(Channel channel) {
        ChannelInvocationHandler cih = (ChannelInvocationHandler) Proxy.getInvocationHandler(channel);
        return cih._backend;
    }

    public static Channel createChannel(CommChannel backend, Class<?> type) {
        InvocationHandler h = new ChannelInvocationHandler(backend);
        Class<?>[] ifaces = new Class[] { ChannelProxy.class, type };
        Object proxy = Proxy.newProxyInstance(ChannelProxy.class.getClassLoader(), ifaces, h);
        return (Channel) proxy;
    }

    public static final class ChannelInvocationHandler implements InvocationHandler {
        private CommChannel _backend;

        ChannelInvocationHandler(CommChannel backend) {
            _backend = backend;
        }

        public String toString() {
            return _backend.toString();
        }

        public boolean equals(Object other) {
            return ((ChannelInvocationHandler) other)._backend.equals(_backend);
        }

        public int hashCode() {
            return _backend.hashCode();
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getDeclaringClass() == Object.class) {
                if (method.equals(METHOD_OBJECT_EQUALS)) {
                    return Boolean.valueOf(this.equals(Proxy.getInvocationHandler(args[0])));
                }
                return method.invoke(this, args);
            }
            return JacobVPU.activeJacobThread().message((Channel)proxy, method, args);
        }
    } // class ChannelInvocationHandler

}
