/**
 * Licensed 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.aries.cdi.test.cases;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.util.Dictionary;
import java.util.Hashtable;

import org.apache.aries.cdi.test.interfaces.Pojo;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.test.junit4.service.ServiceUseRule;

public class DisableComponentTests	 extends AbstractTestCase {

	@Rule
	public ServiceUseRule<ConfigurationAdmin> car = new ServiceUseRule.Builder<ConfigurationAdmin>(ConfigurationAdmin.class).build();

	@Before
	@Override
	public void setUp() throws Exception {
	}

	@After
	@Override
	public void tearDown() throws Exception {
	}

	@Test
	public void testDisableContainerComponent() throws Exception {
		Bundle tb8Bundle = installBundle("tb8.jar");

		try (CloseableTracker<Pojo, Pojo> tracker = track(
				"(&(objectClass=%s)(objectClass=*.%s)(service.bundleid=%s))",
				Pojo.class.getName(),
				"ContainerBean",
				tb8Bundle.getBundleId());) {

			Pojo pojo = tracker.waitForService(timeout);

			assertNotNull(pojo);

			Configuration configurationA = null;

			try {
				configurationA = car.getService().getConfiguration("osgi.cdi.cdi.itests.tb8", "?");

				Dictionary<String, Object> p1 = new Hashtable<>();
				p1.put("cdi-itests.tb8.enabled", false);

				configurationA.update(p1);

				for (int i = 20; (i > 0) && (!tracker.isEmpty()); i--) {
					Thread.sleep(20);
				}

				pojo = tracker.getService();

				assertNull(pojo);

				p1 = new Hashtable<>();
				p1.put("containerBean.enabled", true);

				configurationA.update(p1);

				for (int i = 30; (i > 0) && (tracker.isEmpty()); i--) {
					Thread.sleep(20);
				}

				pojo = tracker.getService();

				assertNotNull(pojo);
			}
			finally {
				if (configurationA != null) {
					try {
						configurationA.delete();
					}
					catch (Exception e) {
						// ignore
					}
				}
				tb8Bundle.uninstall();
			}
		}
	}

	@Test
	public void testDisableSingleComponent() throws Exception {
		Bundle tb8Bundle = installBundle("tb8.jar");

		try (CloseableTracker<Pojo, Pojo> tracker = track(
			"(&(objectClass=%s)(objectClass=*.%s)(service.bundleid=%s))",
			Pojo.class.getName(),
			"SingleComponentBean",
			tb8Bundle.getBundleId());) {

			Pojo pojo = tracker.waitForService(timeout);

			assertNotNull(pojo);

			Configuration configurationA = null;

			try {
				configurationA = car.getService().getConfiguration("osgi.cdi.cdi.itests.tb8", "?");

				Dictionary<String, Object> p1 = new Hashtable<>();
				p1.put("singleComponentBean.enabled", false);

				configurationA.update(p1);

				for (int i = 20; (i > 0) && (!tracker.isEmpty()); i--) {
					Thread.sleep(20);
				}

				pojo = tracker.getService();

				assertNull(pojo);

				p1 = new Hashtable<>();
				p1.put("singleComponentBean.enabled", true);

				configurationA.update(p1);

				for (int i = 20; (i > 0) && (tracker.isEmpty()); i--) {
					Thread.sleep(20);
				}

				pojo = tracker.getService();

				assertNotNull(pojo);
			}
			finally {
				if (configurationA != null) {
					try {
						configurationA.delete();
					}
					catch (Exception e) {
						// ignore
					}
				}
				tb8Bundle.uninstall();
			}
		}
	}

}
