/*
* 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.runtime.itest.components;

import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.annotation.api.Component;
import org.apache.felix.dm.annotation.api.Inject;
import org.apache.felix.dm.annotation.api.ServiceDependency;
import org.apache.felix.dm.annotation.api.Start;
import org.apache.felix.dm.annotation.api.Stop;
import org.apache.felix.dm.annotation.api.ServiceDependency.Any;
import org.apache.felix.dm.itest.util.Ensure;
import org.junit.Assert;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;

/**
 * This test validates that all services can be discovered using annotation and using "(objectClass=*)" filter.
 */
@Component
public class FELIX5337 implements FrameworkListener {
	/**
	 * We wait for an Ensure object which has a name matching this constant.
	 */
	public final static String ENSURE = "Felix5337";
	
	/**
	 * We need the bundle context because we register a framework listener in order to detect
	 * when all bundles have been started.
	 */
	@Inject
	volatile BundleContext m_bctx;
	
	/**
	 * We use DM api in order to count all available services. The services count will be compared to the
	 * number of services found using annotation.
	 */
	@Inject
	DependencyManager m_dm;
	
	/**
	 * The Ensure service is registered by the FELIX5337Test test.
	 */
	@ServiceDependency(filter = "(name=" + ENSURE + ")")
	volatile Ensure m_sequencer;
	
	/**
	 * Number of services found using annotations.
	 */
	volatile int m_services;
	
	/**
	 * Number of services found using DM api.
	 */
	volatile int m_servicesAPI;
	
	/**
	 * Component used to track all services (using DM API).
	 */
	volatile org.apache.felix.dm.Component m_component;
	
	/**
	 * The component used to track all available services (using DM API).
	 */
	public class ApiCallback {
		void bindServiceAPI(Object service) {
			m_servicesAPI++;
		}
	}

	/**
	 * Track all available services using annotation.
	 */
	@ServiceDependency(service=Any.class)
	void bindService(Object service) {
		m_services++; // thread safe, in DM, service callbacks are always thread safe.
	}

	@Start
	void start() {
		m_sequencer.step(1);
		// use DM api to count all available services.
		m_component = m_dm.createComponent().setImplementation(new ApiCallback())
						  .add(m_dm.createServiceDependency().setService("(objectClass=*)").setCallbacks("bindServiceAPI", null));
		m_dm.add(m_component);

		// Register a framework listener to detect when the framework is started (at this point, all services are registered).
		if (m_bctx.getBundle(0).getState() != Bundle.ACTIVE) {
			m_bctx.addFrameworkListener(this);
		} else {
			frameworkEvent(new FrameworkEvent(FrameworkEvent.STARTED, m_bctx.getBundle(), null));
		}
	}

	@Stop
	void stop() {
		m_dm.remove(m_component);
		m_sequencer.step(3);
	}

	@Override
	public void frameworkEvent(FrameworkEvent event) {
		switch (event.getType()) {
		case FrameworkEvent.STARTED:
		    // some services may be registered asynchronously. so, wait 2 seconds to be sure all services are registered (it's dirty, but how to avoid this ?)
		    new Thread(() -> {
		        try
                {
                    Thread.sleep(2000);
                } catch (InterruptedException e)
                {
                }
		        // Make sure all services found using DM api matches the number of services found using annotations.
		        Assert.assertEquals(m_services, m_servicesAPI);
		        m_sequencer.step(2);
		    }).start();
			break;
		}
	}
}
