package jp.sourceforge.shovel.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.annotation.tiger.Binding;
import org.seasar.framework.container.annotation.tiger.BindingType;
import org.seasar.framework.log.Logger;

import jp.sourceforge.shovel.device.IDelayExecutor;
import jp.sourceforge.shovel.device.IDelayExecutorContext;
import jp.sourceforge.shovel.exception.ApplicationException;

public class DelayExecutorQueue extends Thread {
    static Logger logger = Logger.getLogger(DelayExecutorQueue.class);
    
    S2Container container_;
    Map<String, IDelayExecutor> executorMap_;
    BlockingQueue<IDelayExecutorContext> queue_;
    
    @Binding(bindingType=BindingType.NONE)
    public void addDelayExecutor(IDelayExecutor executor) {
        if (executorMap_ == null) {
            executorMap_ = new HashMap<String, IDelayExecutor>();
        }
        executorMap_.put(executor.getExecutorId(), executor);
    }
    @Binding(bindingType=BindingType.NONE)
    public void run() {
        if (queue_ == null) {
            //TODO
            queue_ = new LinkedBlockingQueue<IDelayExecutorContext>(64);
        }
        while (true) {
            try {
                IDelayExecutorContext context = queue_.take();
                for (IDelayExecutor executor : executorMap_.values()) {
                    executor.execute(context);
                }
            } catch (InterruptedException e) {
            } catch (ApplicationException e) {
            }
        }
    }
    @Binding(bindingType=BindingType.NONE)
    public void pushContext(IDelayExecutorContext context) throws ApplicationException {
        try {
            queue_.put(context);
        } catch (InterruptedException e) {
            //TODO
            throw new ApplicationException("");
        }
    }
    @Binding(bindingType=BindingType.NONE)
    public IDelayExecutor getDelayExecutor(String executorId) {
        return executorMap_.get(executorId);
    }
    @Binding(bindingType=BindingType.NONE)
    public IDelayExecutor[] getDelayExecutors() {
        if (executorMap_ == null) {
            return new IDelayExecutor[0];
        }
        return executorMap_.values().toArray(new IDelayExecutor[executorMap_.size()]);
    }
}
