/**************************************************************
 * 
 * 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 com.sun.star.lib.uno.bridges.java_remote;

import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XInstanceProvider;
import com.sun.star.comp.connections.PipedConnection;
import com.sun.star.connection.XConnection;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.lib.uno.environments.java.java_environment;
import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
import com.sun.star.lib.uno.typeinfo.TypeInfo;
import com.sun.star.uno.IQueryInterface;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
import complexlib.ComplexTestCase;
import util.WaitUnreachable;

public final class java_remote_bridge_Test extends ComplexTestCase {
    public String getTestObjectName() {
        return getClass().getName();
    }

    public String[] getTestMethodNames() {
        return new String[] { "test" };
    }

    public void test() throws Exception {
        String protocol = "urp";

        XConnection connectionA = new PipedConnection(new Object[0]);
        XConnection connectionB = new PipedConnection(
            new Object[] { connectionA });
        java_remote_bridge bridgeA = new java_remote_bridge(
            new java_environment(null), null,
            new Object[] { protocol, connectionA, new TestInstanceProvider() });
        java_remote_bridge bridgeB = new java_remote_bridge(
            new java_environment(null), null,
            new Object[] { protocol, connectionB, null });

        testGetInstance(bridgeA, bridgeB);
        testLifeCycle(bridgeA, bridgeB);
    }

    private void testGetInstance(XBridge bridgeA, XBridge bridgeB) {
        assure("return null",
               bridgeB.getInstance(TestInstanceProvider.NAME_NULL) == null);

        try {
            bridgeB.getInstance(TestInstanceProvider.NAME_RUNTIME_EXCEPTION);
            failed("throw RuntimeException");
        } catch (com.sun.star.uno.RuntimeException e) {
            assure("throw RuntimeException",
                   e.getMessage().indexOf(
                       TestInstanceProvider.NAME_RUNTIME_EXCEPTION) != -1);
        }

        try {
            bridgeB.getInstance(
                TestInstanceProvider.NAME_NO_SUCH_ELEMENT_EXCEPTION);
            failed("throw NoSuchElementException");
        } catch (com.sun.star.uno.RuntimeException e) {
            assure("throw NoSuchElementException",
                   e.getMessage().indexOf(
                       TestInstanceProvider.NAME_NO_SUCH_ELEMENT_EXCEPTION)
                   != -1);
        }

        try {
            bridgeA.getInstance(TestInstanceProvider.NAME_ANYTHING);
            failed("no instance provider");
        } catch (com.sun.star.uno.RuntimeException e) {
            assure("no instance provider",
                   e.getMessage().startsWith("unknown OID "));
        }
    }

    private void testLifeCycle(java_remote_bridge bridgeA,
                               java_remote_bridge bridgeB)
        throws InterruptedException
    {
        // Repeatedly, objects are mapped from bridgeA to bridgeB, where proxies
        // for those objects (for the XInterface and TestInterface facets) are
        // created.  The proxies at bridgeB keep both bridges alive; after those
        // proxies have been garbage-collected, both bridges should be disposed.
        // It does not work to map a local object from bridgeA to bridgeB, as
        // bridgeB would find this object as a local one, too (via the shared,
        // static localObjects Registry in java_environment): bridgeB would not
        // create a proxy, would rather send back a "release" to bridgeA, and
        // both bridges would be disposed while the first object is being
        // mapped.  Therefore, a HACK is used to install TestProxy objects
        // (which behave as if they got mapped in to bridgeA from somewhere
        // else) at bridgeA and map those.

        final int COUNT = 100;
        XInterface[] proxyBXInterface = new XInterface[COUNT];
        TestInterface[] proxyBTestInterface = new TestInterface[COUNT];
        for (int i = 0; i < COUNT; ++i) {
            String name = "TestOID" + i;
            Object proxyA = new TestProxy(name);
            bridgeA.getSourceEnvironment().registerInterface(
                proxyA, new String[] { name }, new Type(XInterface.class));

            proxyBXInterface[i] = (XInterface) bridgeB.getInstance(name);

            // map object:
            proxyBTestInterface[i] = UnoRuntime.queryInterface(
                TestInterface.class, proxyBXInterface[i]);
            proxyBTestInterface[i].function();

            // remap object once:
            TestInterface remapped = UnoRuntime.queryInterface(
                TestInterface.class, proxyBXInterface[i]);
            remapped.function();

            // remap object twice:
            remapped = UnoRuntime.queryInterface(
                TestInterface.class, proxyBXInterface[i]);
            remapped.function();
        }

        assure("calls of object method", TestProxy.getCount() == 3 * COUNT);

        // The following checks rely on the implementation detail that mapping
        // different facets of a UNO object (XInterface and TestInterface) leads
        // to different proxies:

        assure("bridge A life count", bridgeA.getLifeCount() == 2 * COUNT);
        assure("bridge B life count", bridgeB.getLifeCount() == 2 * COUNT);
        assure("proxy count", ProxyFactory.getDebugCount() == 2 * COUNT);

        System.out.println("waiting for proxies to become unreachable:");
        for (int i = 0; i < COUNT; ++i) {
            WaitUnreachable u1 = new WaitUnreachable(proxyBXInterface[i]);
            WaitUnreachable u2 = new WaitUnreachable(proxyBTestInterface[i]);
            proxyBXInterface[i] = null;
            proxyBTestInterface[i] = null;
            u1.waitUnreachable();
            u2.waitUnreachable();
        }
        // For whatever strange reason, this sleep seems to be necessary to
        // reliably ensure that even the last proxy's finalization is over
        // before the following assure is executed:
        Thread.sleep(1000);

        assure("proxy count", ProxyFactory.getDebugCount() == 0);

        System.out.println("waiting for pending messages to be done");
        while (bridgeA.getLifeCount() != 0 || bridgeB.getLifeCount() != 0) {
            Thread.sleep(100);
        }

        assure("Zero bridge A life count", bridgeA.getLifeCount() == 0);
        assure("Zero bridge B life count", bridgeB.getLifeCount() == 0);
        assure("Zero proxy count", ProxyFactory.getDebugCount() == 0);
    }

    public interface TestInterface extends XInterface {
        void function();

        TypeInfo[] UNOTYPEINFO = new TypeInfo[] {
            new MethodTypeInfo("function", 0, 0) };
    }

    private static final class TestInstanceProvider
        implements XInstanceProvider
    {
        public Object getInstance(String name) throws NoSuchElementException {
            if (name.equals(NAME_NULL)) {
                return null;
            } else if (name.equals(NAME_RUNTIME_EXCEPTION)) {
                throw new com.sun.star.uno.RuntimeException(
                    getClass().getName() + ", throwing: " + name);
            } else if (name.equals(NAME_NO_SUCH_ELEMENT_EXCEPTION)) {
                throw new NoSuchElementException(
                    getClass().getName() + ", throwing: " + name);
            } else {
                throw new IllegalStateException();
            }
        }

        public static final String NAME_NULL = "return null";
        public static final String NAME_RUNTIME_EXCEPTION
        = "throw RuntimeException";
        public static final String NAME_NO_SUCH_ELEMENT_EXCEPTION
        = "throw NoSuchElementException";
        public static final String NAME_ANYTHING = "anything";
    }

    private static final class TestProxy
        implements com.sun.star.lib.uno.Proxy, IQueryInterface, XInterface,
            TestInterface
    {
        public TestProxy(String oid) {
            this.oid = oid;
        }

        public Object queryInterface(Type type) {
            // type should be either XInterface or TestInterface...
            return this;
        }

        public boolean isSame(Object object) {
            return object instanceof TestProxy
                && oid.equals(((TestProxy) object).oid);
        }

        public String getOid() {
            return oid;
        }

        public void function() {
            synchronized (getClass()) {
                ++count;
            }
        }

        public static synchronized int getCount() {
            return count;
        }

        private final String oid;

        private static int count = 0;
    }
}
