/*
 * Copyright (c) 2010-2012 Dmytro Pishchukhin (http://knowhowlab.org)
 *
 * 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.knowhowlab.osgi.testing.utils;

import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.Version;

import java.util.concurrent.TimeUnit;

/**
 * OSGi Framework utilities class
 * @version 1.1
 * @see org.osgi.framework.BundleContext
 * @see org.osgi.framework.FrameworkListener
 * @see org.osgi.framework.FrameworkEvent
 */
public class FrameworkUtils {
    public static FrameworkEvent waitForFrameworkEvent(BundleContext bc, int bundleId, int eventTypeMask, long timeoutInMillis) {
        return waitForFrameworkEvent(bc, bundleId, eventTypeMask, timeoutInMillis, TimeUnit.MILLISECONDS);
    }

    public static FrameworkEvent waitForFrameworkEvent(BundleContext bc, String symbolicName, int eventTypeMask, long timeoutInMillis) {
        return waitForFrameworkEvent(bc, symbolicName, eventTypeMask, timeoutInMillis, TimeUnit.MILLISECONDS);
    }

    public static FrameworkEvent waitForFrameworkEvent(BundleContext bc, String symbolicName, Version version, int eventTypeMask, long timeoutInMillis) {
        return waitForFrameworkEvent(bc, symbolicName, version, eventTypeMask, timeoutInMillis, TimeUnit.MILLISECONDS);
    }

    public static FrameworkEvent waitForFrameworkEvent(BundleContext bc, int bundleId, int eventTypeMask, long timeout, TimeUnit timeUnit) {
        return null; // todo
    }

    public static FrameworkEvent waitForFrameworkEvent(BundleContext bc, String symbolicName, int eventTypeMask, long timeout, TimeUnit timeUnit) {
        return null; // todo
    }

    public static FrameworkEvent waitForFrameworkEvent(BundleContext bc, String symbolicName, Version version, int eventTypeMask, long timeout, TimeUnit timeUnit) {
        return null; // todo
    }

}

@@ -706,100 +706,55 @@
 ork.
-BundleContext;%0Aimport org.osgi.framework.FrameworkEvent;%0Aimport org.osgi.framework.Version;%0A
+*;%0A%0Aimport java.util.concurrent.CountDownLatch;
 %0Aimp
@@ -1934,36 +1934,303 @@
         
-return null; // todo
+Bundle bundle = BundleUtils.findBundle(bc, bundleId);%0A        if (bundle == null) %7B%0A            throw new IllegalArgumentException(%22bundleId is invalid%22);%0A        %7D%0A        return waitForFrameworkEvent(bc, bundle.getSymbolicName(), bundle.getVersion(), eventTypeMask, timeout, timeUnit);
 %0A    %7D%0A%0A
@@ -2388,37 +2388,104 @@
      return 
-null; // todo
+waitForFrameworkEvent(bc, symbolicName, null, eventTypeMask, timeout, timeUnit);
 %0A    %7D%0A%0A    
@@ -2657,34 +2657,2138 @@
     
-return null; // todo%0A    %7D%0A
+CountDownLatch latch = new CountDownLatch(1);%0A%0A        long timeoutInMillis = timeUnit.toMillis(timeout);%0A        FrameworkListenerImpl listener = new FrameworkListenerImpl(symbolicName, version, eventTypeMask, latch);%0A        bc.addFrameworkListener(listener);%0A%0A        try %7B%0A            return waitForFrameworkEvent(listener, timeoutInMillis, latch);%0A        %7D catch (InterruptedException e) %7B%0A            return null;%0A        %7D finally %7B%0A            bc.removeFrameworkListener(listener);%0A        %7D%0A    %7D%0A%0A    private static FrameworkEvent waitForFrameworkEvent(FrameworkListenerImpl listener, long timeoutInMillis, CountDownLatch latch)%0A            throws InterruptedException %7B%0A        if (timeoutInMillis %3C 0) %7B%0A            throw new IllegalArgumentException(%22timeout value is negative%22);%0A        %7D%0A        if (latch.await(timeoutInMillis, TimeUnit.MILLISECONDS)) %7B%0A            return listener.getFrameworkEvent();%0A        %7D else %7B%0A            return null;%0A        %7D%0A    %7D%0A%0A    private static class FrameworkListenerImpl implements FrameworkListener %7B%0A        private String symbolicName;%0A        private Version version;%0A        private int eventTypeMask;%0A        private CountDownLatch latch;%0A%0A        private FrameworkEvent event;%0A%0A        public FrameworkListenerImpl(String symbolicName, Version version, int eventTypeMask, CountDownLatch latch) %7B%0A            this.symbolicName = symbolicName;%0A            this.version = version;%0A            this.eventTypeMask = eventTypeMask;%0A            this.latch = latch;%0A        %7D%0A%0A        public void frameworkEvent(FrameworkEvent event) %7B%0A            if (match(event)) %7B%0A                this.event = event;%0A                latch.countDown();%0A            %7D%0A        %7D%0A%0A        private boolean match(FrameworkEvent event) %7B%0A            Bundle bundle = event.getBundle();%0A            return bundle.getSymbolicName().equals(symbolicName)%0A                    && (version == null %7C%7C bundle.getVersion().equals(version))%0A                    && (eventTypeMask & event.getType()) == 1;%0A        %7D%0A%0A        public FrameworkEvent getFrameworkEvent() %7B%0A            return event;%0A        %7D%0A    %7D
 %0A%7D%0A

add FrameworkUtils.waitForFrameworkEvent() methods