/**
 * 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.felix.dm.lambda.itest;

import static org.apache.felix.dm.lambda.DependencyManagerActivator.aspect;
import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;

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

import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.junit.Assert;

/**
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
@SuppressWarnings({"rawtypes"})
public class DynamicProxyAspectTest extends TestBase {
    public void testImplementGenericAspectWithDynamicProxyAndFactory() {
        DependencyManager m = getDM();
        // helper class that ensures certain steps get executed in sequence
        Ensure e = new Ensure();
        
        DynamicProxyHandler.resetCounter();
        
        // create two service providers, each providing a different service interface
        Component sp1 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class).build();
        Component sp2 = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface2.class).build();
        
        // create a dynamic proxy based aspect and hook it up to both services
        Component a1 = aspect(m, ServiceInterface.class)
            .rank(10)
            .autoConfig("m_service")
            .factory(new Factory(e, ServiceInterface.class, "ServiceInterfaceProxy"), "create")
            .build();
        
        Component a2 = aspect(m, ServiceInterface2.class)
            .rank(10)
            .autoConfig("m_service")
            .factory(new Factory(e, ServiceInterface2.class, "ServiceInterfaceProxy2"), "create")
            .build();

        // create a client that invokes a method on boths services, validate that it goes
        // through the proxy twice
        Component sc = component(m)
            .impl(new ServiceConsumer(e))
            .withSvc(true, ServiceInterface.class, ServiceInterface2.class).build();
        
        // register both producers, validate that both services are started
        m.add(sp1);
        e.waitForStep(1, 2000);
        m.add(sp2);
        e.waitForStep(2, 2000);
        
        // add both aspects, and validate that both instances have been created
        m.add(a1);
        m.add(a2);
        e.waitForStep(4, 4000);
        
        // add the client, which will automatically invoke both services
        m.add(sc);
        
        // wait until both services have been invoked
        e.waitForStep(6, 4000);
        
        // make sure the proxy has been called twice
        Assert.assertEquals("Proxy should have been invoked this many times.", 2, DynamicProxyHandler.getCounter());
        
        m.remove(sc);
        m.remove(a2);
        m.remove(a1);
        m.remove(sp2);
        m.remove(sp1);
        m.remove(a2);
        m.remove(a1);
    }

    public void testImplementGenericAspectWithDynamicProxyAndFactoryRef() {
        DependencyManager m = getDM();
        // helper class that ensures certain steps get executed in sequence
        Ensure e = new Ensure();
        
        DynamicProxyHandler.resetCounter();

        // create two service providers, each providing a different service interface
        Component sp1 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class).build();
        Component sp2 = component(m).impl(new ServiceProvider2(e)).provides(ServiceInterface2.class).build();
        
        // create a dynamic proxy based aspect and hook it up to both services
        Component a1 = aspect(m, ServiceInterface.class).rank(10).autoConfig("m_service")
            .factory(() -> new Factory(e, ServiceInterface.class, "ServiceInterfaceProxy"), Factory::create).build();
        Component a2 = aspect(m, ServiceInterface2.class).rank(10).autoConfig("m_service")
            .factory(() -> new Factory(e, ServiceInterface2.class, "ServiceInterfaceProxy2"), Factory::create).build();

        // create a client that invokes a method on boths services, validate that it goes
        // through the proxy twice
        Component sc = component(m)
            .impl(new ServiceConsumer(e))
            .withSvc(true, ServiceInterface.class, ServiceInterface2.class).build();
        
        // register both producers, validate that both services are started
        m.add(sp1);
        e.waitForStep(1, 2000);
        m.add(sp2);
        e.waitForStep(2, 2000);
        
        // add both aspects, and validate that both instances have been created
        m.add(a1);
        m.add(a2);
        e.waitForStep(4, 4000);
        
        // add the client, which will automatically invoke both services
        m.add(sc);
        
        // wait until both services have been invoked
        e.waitForStep(6, 4000);
        
        // make sure the proxy has been called twice
        Assert.assertEquals("Proxy should have been invoked this many times.", 2, DynamicProxyHandler.getCounter());
        
        m.remove(sc);
        m.remove(a2);
        m.remove(a1);
        m.remove(sp2);
        m.remove(sp1);
        m.remove(a2);
        m.remove(a1);        
    }
    
    static interface ServiceInterface {
        public void invoke(Runnable run);
    }
    
    static interface ServiceInterface2 {
        public void invoke(Runnable run);
    }
    
    static class ServiceProvider implements ServiceInterface {
        private final Ensure m_ensure;
        public ServiceProvider(Ensure e) {
            m_ensure = e;
        }
        public void start() {
            m_ensure.step(1);
        }
        public void invoke(Runnable run) {
            run.run();
        }
    }
    
    static class ServiceProvider2 implements ServiceInterface2 {
        private final Ensure m_ensure;
        public ServiceProvider2(Ensure ensure) {
            m_ensure = ensure;
        }
        public void start() {
            m_ensure.step(2);
        }
        public void invoke(Runnable run) {
            run.run();
        }
    }
    
    static class ServiceConsumer implements Runnable {
        private volatile ServiceInterface m_service;
        private volatile ServiceInterface2 m_service2;
        private final Ensure m_ensure;

        public ServiceConsumer(Ensure e) {
            m_ensure = e;
        }
        
        public void init() {
            Thread t = new Thread(this);
            t.start();
        }
        
        public void run() {
            m_service.invoke(Ensure.createRunnableStep(m_ensure, 5));
            m_service2.invoke(Ensure.createRunnableStep(m_ensure, 6));
        }
    }
    
    static class DynamicProxyHandler implements InvocationHandler {
        public volatile Object m_service; // ISSUE, we cannot inject into "Object" at the moment
        private final String m_label;
        private static volatile int m_counter = 0;

        public DynamicProxyHandler(String label) {
            m_label = label;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("IIIIIIINVOKE--------------------------" + method.getName());
            if (m_service == null) {
                Assert.fail("No service was injected into dynamic proxy handler " + m_label);
            }
            Method m = m_service.getClass().getMethod(method.getName(), method.getParameterTypes());
            if (m == null) {
                Assert.fail("No method " + method.getName() + " was found in instance " + m_service + " in dynamic proxy handler " + m_label);
            }
            if (method.getName().equals("invoke")) {
                // only count methods called 'invoke' because those are actually the ones
                // both interfaces implement (and the dynamic proxy might be invoked for
                // other methods, such as toString() as well)
                m_counter++;
            }
            return m.invoke(m_service, args);
        }
        
        public static int getCounter() {
            return m_counter;
        }
        
        public static void resetCounter() {
            m_counter = 0;
        }
    }
    
    static class Factory {
        private final String m_label;
        private Class m_class;
        private final Ensure m_ensure;
        
        public Factory(Ensure ensure, Class clazz, String label) {
            m_ensure = ensure;
            m_class = clazz;
            m_label = label;
        }
        
        public Object create() {
            m_ensure.step();
            return Proxy.newProxyInstance(m_class.getClassLoader(), new Class[] { m_class }, new DynamicProxyHandler(m_label));
        }
    }
}
