/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  The ASF licenses this file to You
 * 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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.business;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.util.RollerConstants;
import org.apache.roller.weblogger.business.runnable.ContinuousWorkerThread;
import org.apache.roller.weblogger.business.runnable.HitCountProcessingJob;
import org.apache.roller.weblogger.business.runnable.WorkerThread;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.Weblog;


/**
 * Queue's up incoming hit counts so that they can be recorded to the db in
 * an asynchronous manner at give intervals.
 *
 * We also start up a single thread which runs continously to take the queued
 * hit counts, tally them, and record them into the db.
 *
 * TODO: we may want to make this an interface that is pluggable if there is
 *   some indication that users want to override this implementation.
 */
public final class HitCountQueue {
    
    private static Log log = LogFactory.getLog(HitCountQueue.class);
    
    private static HitCountQueue instance = null;
    
    private WorkerThread worker = null;
    private List<String> queue = null;
    
    
    static {
        instance = new HitCountQueue();
    }
    
    
    // non-instantiable because we are a singleton
    private HitCountQueue() {
        int sleepTime = 3 * RollerConstants.MIN_IN_MS;
        String sleep = WebloggerConfig.getProperty("hitcount.queue.sleepTime", "180");
        
        try {
            // convert input in seconds to ms
            sleepTime = Integer.parseInt(sleep) * RollerConstants.SEC_IN_MS;
        } catch(NumberFormatException nfe) {
            log.warn("Invalid sleep time ["+sleep+"], using default");
        }
        
        // create the hits queue
        this.queue = Collections.synchronizedList(new ArrayList<String>());
        
        // start up a worker to process the hits at intervals
        HitCountProcessingJob job = new HitCountProcessingJob();
        worker = new ContinuousWorkerThread("HitCountQueueProcessor", job, sleepTime);
        worker.start();
    }
    
    
    public static HitCountQueue getInstance() {
        return instance;
    }
    
    
    public void processHit(Weblog weblog) {
        
        // if the weblog isn't null then just drop its handle in the queue
        // each entry in the queue is a weblog handle and indicates a single hit
        if(weblog != null) {
            this.queue.add(weblog.getHandle());
        }
    }
    
    
    public List<String> getHits() {
        return new ArrayList<String>(this.queue);
    }
    
    
    /**
     * Reset the queued hits.
     */
    public synchronized void resetHits() {
        this.queue = Collections.synchronizedList(new ArrayList<String>());
    }
    
    
    /**
     * clean up.
     */
    public void shutdown() {
        
        if(this.worker != null) {
            log.info("stopping worker "+this.worker.getName());
            worker.interrupt();
            try {
                worker.join(RollerConstants.GRACEFUL_SHUTDOWN_WAIT_IN_MILLISECONDS);
            } catch (InterruptedException e) {
                log.debug(e.getMessage(), e);
            }
        }
        
    }
    
}
