/*
 * Copyright, 2010, Nico Schmoigl: 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
 * <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>.
 * 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.
 * Origin: http://blog.schmoigl-online.de
 */
package tutorial.example4var;

import java.util.Date;
import java.util.Vector;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import tutorial.example2.service.DictionaryService;

public class Activator implements BundleActivator {

    // reference to the BundleContext
    private BundleContext ctx;

    // reference to the Thread that we will use to periodically test the referneces
    private TestThread tt;

    // The service tacker object.
    private ServiceTracker m_tracker = null;

    // List of references to DictionaryServices that we got initially on startup
    private Vector<DictionaryService> initialDictServices = new Vector<DictionaryService>();

    /**
     * start routine for the Bundle
     * @param arg0 reference to the BundleContext in which this bundle should run
     * @throws java.lang.Exception may throw any exception
     */
    public void start(BundleContext arg0) throws Exception {
        this.ctx = arg0;

        // initialize the tracker to the Dictionary Services for all possible languages
        m_tracker = new ServiceTracker(
            ctx,
            ctx.createFilter(
                "(&" +
                    "(objectClass=" + DictionaryService.class.getName() + ")" +
                    "(Language=*)" +
                 ")"),
            null);
        m_tracker.open();

        // fetch the services which are available NOW!
        Object[] olist = m_tracker.getServices();
        // convert the list of gained services into the list of initial DictionaryServices
        for (Object o : olist) {
            DictionaryService ds = (DictionaryService) o;
            initialDictServices.add(ds);
        }

        // create a new TestThread which we will use for testing
        this.tt = new TestThread();
        // and start it
        this.tt.start();
    }

    /**
     * triggered when the bundle should be stopped
     * @param arg0 the BundleContext in which this bundle is currently running
     * @throws java.lang.Exception never thrown (but allowed to be thrown)
     */
    public void stop(BundleContext arg0) throws Exception {
        // signalize that the TestThread should stop on next possibility
        this.tt.setShouldRun(false);
    }

    /**
     * local declaration of a private class implementing a Thread
     * The thread will seize activity for a short time frame; on activity
     * it will fetch all references available for the DirectoryService
     * and check each object which language it accepts. Based on this
     * the "type" of the DictionaryService can be detected.
     */
    private class TestThread extends Thread {

        // member variable to start an indicator whether the thread should
        // still run or not
        protected boolean shouldRun;

        /**
         * checks if the thread should still run or should stop
         * @return the value of shouldRun
         */
        public boolean isShouldRun() {
            return shouldRun;
        }

        /**
         * sets if the thread should still run or stop running
         * @param shouldRun new value of shouldRun
         */
        public void setShouldRun(boolean shouldRun) {
            this.shouldRun = shouldRun;
        }


        /**
         * constructor; forwarding to the Thread constructor accordingly
         * and set the ShouldRun attribute to true
         */
        public TestThread() {
            super("TestThread");
            this.setShouldRun(true);
        }

        /**
         * implementation of the test routine; as long as the thread should
         * run the thread will print out information about the types of
         * the DictionaryServices which were available on startup and those
         * which are currently available via the service tracker.
         * Between each check the thread waits five seconds not to spoil
         * the output on the screen.
         */
        @Override
        public void run() {
            while (this.isShouldRun()) {
                System.err.println(new Date());
                for (int i = 0;i<initialDictServices.size();i++) {
                    System.err.println("initial DictService "+i+": "+getDictType(initialDictServices.elementAt(i)));
                }

                Object[] olist = m_tracker.getServices();
                int i = 0;
                for (Object o : olist) {
                    DictionaryService ds = (DictionaryService) o;
                    System.err.println("current DictService "+i+": "+getDictType(ds));
                    i++;
                }

                try {
                    Thread.sleep(5*1000);
                } catch (InterruptedException ex) {
                    // interrupted; can be ignored
                }

            }
        }

        /**
         * finds out which language a given DictionaryService provides and thus
         * determines the "type" of the Dictionary Service
         * @param ds the DictionaryService which should be tested
         * @return the name of the language which the DictionaryService accepts;
         * "unknown" if the routine was unable to determine it.
         */
        private String getDictType(DictionaryService ds) {
            if (ds.checkWord("au"))
                return "french (or meta)";

            if (ds.checkWord("welcome"))
                return "english";

            if (ds.checkWord("willkommen"))
                return "german";

            return "unknown";
        }

    }

}
