/*
 * 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.component;

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

/**
 * Test which validates multi-dependencies combination.
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
@SuppressWarnings({"unchecked", "rawtypes", "serial"})
public class MultipleExtraDependencyTest extends TestBase {
    public void testMultipleExtraDependencies()
    {
        DependencyManager m = getDM();
        Ensure e = new Ensure();
        
        Component sp2 = component(m)
              .impl(ServiceProvider2.class).provides(ServiceProvider2.class)
              .withSvc(Runnable.class, srv->srv.filter("(foo=bar)").required(false).autoConfig("m_runnable"))
              .withSvc(Sequencer.class, srv->srv.add("bind"))
              .composition("getComposition")
              .build();

        Component sp = component(m)
              .impl(ServiceProvider.class)
              .provides(ServiceInterface.class, foo -> "bar")
              .start("start").stop("stop")
              .withSvc(Sequencer.class, srv->srv.autoConfig("m_sequencer"))
              .withSvc(ServiceProvider2.class, srv->srv.add("bind").remove("unbind"))
              .build();
        
        Component sc = component(m)
              .impl(ServiceConsumer.class)
              .start("start").stop("stop")
              .withSvc(Sequencer.class, srv->srv.autoConfig("m_sequencer"))
              .withSvc(ServiceInterface.class, srv->srv.filter("(foo=bar)").autoConfig("m_service"))
              .build();
        
        Component sequencer = component(m)
           .impl(new SequencerImpl(e))
           .provides(Sequencer.class.getName())
           .build();
           
        m.add(sp2);
        m.add(sp);
        m.add(sc);
        m.add(sequencer);
        
        // Check if ServiceProvider component have been initialized orderly
        e.waitForStep(7, 5000);
        
        // Stop the test.annotation bundle
        m.remove(sequencer);
        m.remove(sp);
        m.remove(sp2);
        m.remove(sc);
        
        // And check if ServiceProvider2 has been deactivated orderly
        e.waitForStep(11, 5000);
    }
    
    public interface Sequencer
    {
        void step();
        void step(int step);
        void waitForStep(int step, int timeout);
    }
    
    public static class SequencerImpl implements Sequencer {
        Ensure m_ensure;
        
        public SequencerImpl(Ensure e)
        {
            m_ensure = e;
        }
        
        public void step()
        {
            m_ensure.step();
        }

        public void step(int step)
        {
            m_ensure.step(step);
        }

        public void waitForStep(int step, int timeout)
        {
            m_ensure.waitForStep(step, timeout);
        }  
    }
    
    public interface ServiceInterface
    {
        public void doService();
    }
    
    public static class ServiceConsumer
    {
        volatile Sequencer m_sequencer;
        volatile ServiceInterface m_service;

        void start()
        {
            m_sequencer.step(6);
            m_service.doService();
        }

        void stop()
        {
            m_sequencer.step(8);
        }
    }
    
    public static class ServiceProvider implements ServiceInterface
    {
        Sequencer m_sequencer;
        ServiceProvider2 m_serviceProvider2;

        void bind(ServiceProvider2 provider2)
        {
            m_serviceProvider2 = provider2;
        }

        void start()
        {
            m_serviceProvider2.step(4);
            m_sequencer.step(5);
        }

        void stop()
        {
            m_sequencer.step(9);
        }

        void unbind(ServiceProvider2 provider2)
        {
            m_sequencer.step(10);
        }

        public void doService()
        {
            m_sequencer.step(7);
        }
    }

    public static class ServiceProvider2
    {
        Composite m_composite = new Composite();
        Sequencer m_sequencer;
        Runnable m_runnable;

        void bind(Sequencer seq)
        {
            m_sequencer = seq;
            m_sequencer.step(1);
        }

        void start()
        {
            m_sequencer.step(3);
            m_runnable.run(); // NullObject
        }

        public void step(int step) // called by ServiceProvider.start() method 
        { 
            m_sequencer.step(step);
        }
        
        void stop()
        {
            m_sequencer.step(11);
        }

        Object[] getComposition()
        {
            return new Object[] { this, m_composite };
        }
    }
    
    public static class Composite
    {
        void bind(Sequencer seq)
        {
            seq.step(2);
        }
    }
}
