package org.limewire.statistic;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.limewire.lifecycle.Service;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

/**
 * Manages recording {@link Statistic Statistics}.  This will handle
 * ensuring that every statistic added to this accumulator is stored
 * every second.
 */
@Singleton
final class StatisticsAccumulatorImpl implements StatisticAccumulator, Service {
	
    private final ScheduledExecutorService backgroundExecutor;

    private volatile ScheduledFuture<?> scheduledFuture;
    
	private final List<Statistic> basicStatistics = new CopyOnWriteArrayList<Statistic>();
	
	@Inject
	StatisticsAccumulatorImpl(@Named("backgroundExecutor") ScheduledExecutorService backgroundExecutor) {
	    this.backgroundExecutor = backgroundExecutor;
	}
	
	public void initialize() {
	}
	
	public void start() {
	    if(scheduledFuture != null)
	        throw new IllegalStateException("already started!");
	    scheduledFuture = backgroundExecutor.scheduleWithFixedDelay(new Runner(), 0, 1000, TimeUnit.MILLISECONDS);
	}
	
	public void stop() {
	    ScheduledFuture<?> f = scheduledFuture;
	    if(f != null) {
	        f.cancel(false);
	        scheduledFuture = null;
	    }
	}

	/* (non-Javadoc)
     * @see org.limewire.statistic.StatisticAccumulator#addBasicStatistic(org.limewire.statistic.Statistic)
     */
	public void addBasicStatistic(Statistic stat) {
		basicStatistics.add(stat);
	}

	private class Runner implements Runnable {
    	public void run() {
            for(Statistic stat : basicStatistics) {
				stat.storeCurrentStat();
    		}
    	}
	}

}
