/*
 * 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;
import org.junit.Assert;

/**
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class MultipleExtraDependenciesTest extends TestBase {
    /**
     * Check that list of extra dependencies (defined from init method) are handled properly.
     * The extra dependencies are added using a List object (Component.add(List)).
     * A component c1 will define two extra dependencies over *available* c4/c5 services.
     */
     public void testWithTwoAvailableExtraDependency() {   
         DependencyManager m = getDM();
         // Helper class that ensures certain steps get executed in sequence
         Ensure e = new Ensure();
         Component c1 = component(m).provides(Service1.class).impl(new MyComponent1(e)).withSvc(Service2.class, srv->srv.autoConfig("m_service2")).build();
         Component c2 = component(m).impl(new MyComponent2(e)).withSvc(Service1.class, srv->srv.required(false).autoConfig(false).add("added")).build();
         Component c3 = component(m).provides(Service2.class).impl(Service2Impl.class).build();
         Component c4 = component(m).impl(Service3Impl1.class).provides(Service3.class, "type", "xx").build();
         Component c5 = component(m).impl(Service3Impl2.class).provides(Service3.class, "type", "yy").build();

         System.out.println("\n+++ Adding c2 / MyComponent2");
         m.add(c2);
         System.out.println("\n+++ Adding c3 / Service2");
         m.add(c3);
         System.out.println("\n+++ Adding c4 / Service3(xx)");
         m.add(c4);
         System.out.println("\n+++ Adding c5 / Service3(yy)");
         m.add(c5);
         System.out.println("\n+++ Adding c1 / MyComponent1");
         // c1 have declared two extra dependency on Service3 (xx/yy).
         // both extra dependencies are available, so the c1 component should be started immediately.
         m.add(c1);
         e.waitForStep(3, 3000);
         m.clear();
     }

    /**
     * Check that list of extra dependencies (defined from init method) are handled properly.
     * The extra dependencies are added using a List object (Component.add(List)).
     * A component c1 will define two extra dependencies over c4/c5. At the point c1.init()
     * is adding the two extra dependencies from its init method, c4 is available, but not c5.
     * So, c1 is not yet activated.
     * Then c5 is added, and it triggers the c1 activation ...
     */
    public void testWithOneAvailableExtraDependency() {  
        DependencyManager m = getDM();
        // Helper class that ensures certain steps get executed in sequence
        Ensure e = new Ensure();
        Component c1 = component(m).provides(Service1.class).impl(new MyComponent1(e)).withSvc(Service2.class, srv->srv.autoConfig("m_service2")).build();
        Component c2 = component(m).impl(new MyComponent2(e)).withSvc(Service1.class, srv->srv.required(false).autoConfig(false).add("added")).build();
        Component c3 = component(m).provides(Service2.class).impl(Service2Impl.class).build();
        Component c4 = component(m).impl(Service3Impl1.class).provides(Service3.class, "type", "xx").build();
        Component c5 = component(m).impl(Service3Impl2.class).provides(Service3.class, "type", "yy").build();

        System.out.println("\n+++ Adding c2 / MyComponent2");
        m.add(c2);
        System.out.println("\n+++ Adding c3 / Service2");
        m.add(c3);
        System.out.println("\n+++ Adding c4 / Service3(xx)");
        m.add(c4);
        System.out.println("\n+++ Adding c1 / MyComponent1");
        m.add(c1);

        // c1 have declared two extra dependency on Service3 (xx/yy).
        // So, because we have not yet added c5 (yy), c1 should not be started currently.
        // But, now, we'll add c5 (Service3/yy) and c1 should then be started ...
        System.out.println("\n+++ Adding c5 / Service3(yy)");
        m.add(c5);
        e.waitForStep(3, 3000);
        m.clear();
    }


    public interface Service1 {}
    public interface Service2 {}
    public interface Service3 {}

    public static class Service2Impl implements Service2 {}
    public static class Service3Impl1 implements Service3 {}
    public static class Service3Impl2 implements Service3 {}

    public static class MyComponent1 implements Service1 {
        Service2 m_service2;
        Service3 m_service3_xx;
        Service3 m_service3_yy;
        Ensure m_ensure;
        
        public MyComponent1(Ensure e) {
            m_ensure = e;
        }

        void init(Component c) {
            m_ensure.step(1);
            // Service3/xx currently available
            // Service3/yy not yet available

            component(c, comp -> comp
                .withSvc(Service3.class, srv->srv.filter("(type=xx)").autoConfig("m_service3_xx"))
                .withSvc(Service3.class, srv->srv.filter("(type=yy)").autoConfig("m_service3_yy")));
        }
        
        void start() {
            System.out.println("MyComponent1.start");
            Assert.assertNotNull(m_service2);
            Assert.assertNotNull(m_service3_xx);
            Assert.assertNotNull(m_service3_yy);
            m_ensure.step(2);
        }
    }
    
    public static class MyComponent2 {
        Ensure m_ensure;
        
        public MyComponent2(Ensure e) {
            m_ensure = e;
        }

        void added(Service1 s1) {
            System.out.println("MyComponent2.bind(" + s1 + ")");
            Assert.assertNotNull(s1);
            m_ensure.step(3);
        }
        
        void start() {
            System.out.println("MyComponent2.start");
        }
    }
}
