/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.util.apache.avalon.cornerstone.services.scheduler;

import fr.gouv.culture.sdx.utils.Utilities;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.NoSuchElementException;

public class SimpleTimeScheduler implements TimeScheduler {

    protected Hashtable triggers = new Hashtable();
    protected Hashtable targets = new Hashtable();


    public void addTrigger(String name, TimeTrigger trigger, Target target) {
        if (Utilities.checkString(name) && trigger != null && target != null) {
            this.triggers.put(name, trigger);
            this.targets.put(name, target);
        }
    }

    public void removeTrigger(String name)
            throws NoSuchElementException {
        if (Utilities.checkString(name)) {
            this.triggers.remove(name);
            this.targets.remove(name);
        }
    }

    public void resetTrigger(String name)
            throws NoSuchElementException {
        if (Utilities.checkString(name)) {
            TimeTrigger trigger = (TimeTrigger) this.triggers.get(name);
            if (trigger != null)
                trigger.reset();
        }
    }


    public void start() {
        Enumeration trigKeys = this.triggers.keys();
        if (trigKeys != null) {
            while (trigKeys.hasMoreElements()) {
                String trigName = (String) trigKeys.nextElement();
                launchScheduleThread(trigName);

            }
        }

    }

    protected synchronized void launchScheduleThread(final String triggerName) {
        if (triggerName != null) {
            final TimeTrigger trigger = (TimeTrigger) this.triggers.get(triggerName);
            final Target target = (Target) this.targets.get(triggerName);
            if (trigger != null && target != null) {
                long now = System.currentTimeMillis();
                long next = trigger.getTimeAfter(now);
                final long timeUntilTrigger = next - now;

                new Thread() {
                    public void run() {
                        synchronized (this) {
                            try {
                                wait(timeUntilTrigger);
                                // wait for trigger time or signal
                                target.targetTriggered(triggerName);
                                launchScheduleThread(triggerName);

                            } catch (InterruptedException ignore) {
                            }
                        }

                    }
                }.start();

            }
        }
    }


}
