package org.greenstone.gsdl3.service;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.log4j.Logger;
import org.greenstone.gsdl3.util.DerbyWrapper;
import org.greenstone.gsdl3.util.GSXML;
import org.greenstone.gsdl3.util.XMLConverter;
import org.greenstone.util.GlobalProperties;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class UserTracker extends ServiceRack
{
	static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.UserTracker.class.getName());

	/**************************************************
	 * The list of services the User Tracker supports *
	 *************************************************/
	protected static final String RECORD_USER_ACTION = "RecordUserAction";
	protected static final String GET_ACTIVITY_ON_PAGE = "GetActivityOnPage";
	/*************************************************/

	String[] services = { RECORD_USER_ACTION, GET_ACTIVITY_ON_PAGE };

  // the parameters these services use
  protected static final String USER_PARAM = "username";
  protected static final String COLLECTION_PARAM = "collection";
  protected static final String SITE_PARAM = "site";
  protected static final String OID_PARAM = "oid";
  protected static final String ACTION_PARAM = "action";
  
	/** configure this service */
	public boolean configure(Element info, Element extra_info)
	{
		if (!super.configure(info, extra_info))
		{
			return false;
		}

		logger.info("Configuring UserTracker...");
		this.config_info = info;

		for (int i = 0; i < services.length; i++)
		{
			Element service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
			service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
			service.setAttribute(GSXML.NAME_ATT, services[i]);
			this.short_service_info.appendChild(service);
		}

		// should any of the params be saved to the session?
		// assuming not at this stage. But if they do need to be, then
		// sture them here in save_params.
		// this.save_params.add(XXX_PARAM);
		return true;
	}

	protected Element getServiceDescription(Document doc, String service_id, String lang, String subset)
	{
		for (int i = 0; i < services.length; i++)
		{
			if (service_id.equals(services[i]))
			{
				Element service_elem = doc.createElement(GSXML.SERVICE_ELEM);
				service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
				service_elem.setAttribute(GSXML.NAME_ATT, services[i]);
				return service_elem;
			}
		}

		return null;
	}

	protected synchronized Element processRecordUserAction(Element request)
	{
	  Document result_doc = XMLConverter.newDOM();
		Element result = GSXML.createBasicResponse(result_doc, RECORD_USER_ACTION);

		Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
		if (paramList == null)
		{
			GSXML.addError(result, "Request has no parameter list");
			return result;
		}

		HashMap<String, Serializable> params = GSXML.extractParams(paramList, true);
		String username = (String) params.get(USER_PARAM);
		String collection = (String) params.get(COLLECTION_PARAM);
		String site = (String) params.get(SITE_PARAM);
		String oid = (String) params.get(OID_PARAM);
		String action = (String) params.get(ACTION_PARAM);

		DerbyWrapper database = new DerbyWrapper(DerbyWrapper.USERSDB_DIR);
		database.addUserAction(username, site, collection, oid, action);
		database.closeDatabase();

		return result;
	}

	protected synchronized Element processGetActivityOnPage(Element request)
	{
	  Document result_doc = XMLConverter.newDOM();
		Element result = GSXML.createBasicResponse(result_doc, GET_ACTIVITY_ON_PAGE);
		try
		{

			Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
			if (paramList == null)
			{
				GSXML.addError(result, "Request has no parameter list");
				return result;
			}

			HashMap<String, Serializable> params = GSXML.extractParams(paramList, true);
			String collection = (String) params.get(COLLECTION_PARAM);
			String site = (String) params.get(SITE_PARAM);
			String oid = (String) params.get(OID_PARAM);

			DerbyWrapper database = new DerbyWrapper(DerbyWrapper.USERSDB_DIR);
			ArrayList<HashMap<String, String>> userActions = database.getMostRecentUserActions(site, collection, oid);

			Element userList = result_doc.createElement("userList");
			for (HashMap<String, String> userAction : userActions)
			{
				Element user = result_doc.createElement("user");
				user.setAttribute("username", userAction.get("username"));
				user.setAttribute("action", userAction.get("action"));
				userList.appendChild(user);
			}
			result.appendChild(userList);
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
		return result;
	}
}
