/*
 * Copyright 2002-2005 Uwyn bvba/sprl <info[remove] at uwyn dot com>
 * Distributed under the terms of the GNU Lesser General Public
 * License, v2.1 or later
 *
 * $Id: ReindexSearch.java 1197 2005-01-07 19:06:58Z gbevin $
 */
package com.uwyn.drone.webui.elements.admin;

import com.uwyn.drone.tools.SearchTool;
import com.uwyn.drone.tools.SearchToolListener;
import com.uwyn.rife.engine.Element;
import com.uwyn.rife.template.Template;
import java.text.NumberFormat;

public class ReindexSearch extends Element
{
	private static Object			sIndexingMonitor = new Object();
	private static IndexingThread	sIndexingThread = null;
	
	private Template	mTemplate = null;
	
	public void initialize()
	{
		mTemplate = getHtmlTemplate("drone.admin.reindex_search");
	}
	
	public void processElement()
	{
		synchronized (sIndexingMonitor)
		{
			if (null == sIndexingThread)
			{
				if (hasSubmission("confirm"))
				{
					sIndexingThread = new IndexingThread();
					new Thread(sIndexingThread).start();
					while (!sIndexingThread.hasStartedIndexing())
					{
						try
						{
							Thread.sleep(100);
						}
						catch (InterruptedException e)
						{
							// just continue processing
						}
						
						Thread.yield();
					}
				}
			}
			
			if (sIndexingThread != null)
			{
				mTemplate.setBlock("head_tags", "head_refresh");
				
				int percentage = (int)((((double)sIndexingThread.getProcessedCount()/sIndexingThread.getTotalCount())*1000d)/10d);
				if (100 == percentage)
				{
					mTemplate.setBlock("authenticated_content", "optimizing_content");
				}
				else
				{
					mTemplate.setBlock("authenticated_content", "busy_content");
					mTemplate.setValue("percentage", percentage);
					NumberFormat format = NumberFormat.getInstance();
					format.setMinimumIntegerDigits(2);
					long eta_ms = sIndexingThread.getEta();
					if (eta_ms >= 0)
					{
						long eta_min = eta_ms/60000;
						long eta_s = (eta_ms-(eta_min*60000))/1000;
						mTemplate.setValue("eta_min", eta_min);
						mTemplate.setValue("eta_s", format.format(eta_s));
						mTemplate.setBlock("eta", "eta");
					}
					mTemplate.setValue("processedCount", sIndexingThread.getProcessedCount());
					mTemplate.setValue("totalCount", sIndexingThread.getTotalCount());
				}
			}
		}
		
		print(mTemplate);
	}
	
	private class IndexingThread implements Runnable, SearchToolListener
	{
		private SearchTool	mSearchTool = null;
		private int			mProcessedCount = 0;
		private int			mTotalCount = 0;
		private boolean		mStartedIndexing = false;
		private long		mStart = 0L;
		
		public synchronized boolean hasStartedIndexing()
		{
			return mStartedIndexing;
		}
		
		public int getProcessedCount()
		{
			return mProcessedCount;
		}
		
		public int getTotalCount()
		{
			return mTotalCount;
		}
		
		public synchronized void indexStep(int processedCount, int totalCount)
		{
			if (!mStartedIndexing)
			{
				mStartedIndexing = true;
				mStart = System.currentTimeMillis();
			}
			mProcessedCount = processedCount;
			mTotalCount = totalCount;
		}
		
		public long getEta()
		{
			if (0 == mProcessedCount)
			{
				return -1;
			}
			
			long elapsed = System.currentTimeMillis()-mStart;
			return (long)(((double)elapsed/mProcessedCount)*mTotalCount)-elapsed;
		}
		
		public void run()
		{
			mSearchTool = new SearchTool();
			mSearchTool.reindexFull(this);

			synchronized (sIndexingMonitor)
			{
				sIndexingThread = null;
			}
		}
	}
}
