/****************************************************************************
 *  This software is part of the gCube Project.
 *  Site: http://www.gcube-system.org/
 ****************************************************************************
 * The gCube/gCore software is licensed as Free Open Source software
 * conveying to the EUPL (http://ec.europa.eu/idabc/eupl).
 * The software and documentation is provided by its authors/distributors
 * "as is" and no expressed or
 * implied warranty is given for its use, quality or fitness for a
 * particular case.
 ****************************************************************************
 * Filename: Sweeper.java
 ****************************************************************************
 * @author <a href="mailto:daniele.strollo@isti.cnr.it">Daniele Strollo</a>
 ***************************************************************************/

package org.gcube.portlets.admin.resourcesweeper.server;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.contexts.GHNContext.Status;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.QueryParameter;
import org.gcube.common.core.informationsystem.client.XMLResult;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericQuery;
import org.gcube.common.core.resources.GCUBEHostingNode;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.common.core.utils.logging.GCUBEClientLog;
import org.gcube.portlets.admin.resourcesweeper.shared.SweeperActions;
import org.gcube.resourcemanagement.support.server.gcube.queries.QueryLoader;
import org.gcube.resourcemanagement.support.server.gcube.queries.QueryLocation;
import org.gcube.resourcemanagement.support.server.managers.resources.GHNManager;
import org.gcube.resourcemanagement.support.server.managers.resources.RunningInstanceManager;

import com.extjs.gxt.ui.client.data.ModelData;

/**
 * @author Massimiliano Assante (ISTI-CNR)
 *
 */
public class Sweeper {
	//TODO: Make it configurable from a property file
	public static String LIVE_GHN_MAX_MINUTES = "40";
	
	static GCUBEClientLog _log = new GCUBEClientLog(Sweeper.class); 

	
	protected ArrayList<String> applyQuery(GCUBEScope queryScope, QueryLocation queryPath, QueryParameter... params) throws Exception {
		ISClient client = GHNContext.getImplementation(ISClient.class);
		GCUBEGenericQuery isQuery = null;
		isQuery = client.getQuery(GCUBEGenericQuery.class);
		isQuery.setExpression(QueryLoader.getQuery(queryPath));
		if (params != null && params.length > 0) {
			isQuery.addParameters(params);
		}
		List<XMLResult> results = client.execute(isQuery, queryScope);
		ArrayList<String> retval = new ArrayList<String>();

		for (XMLResult elem : results) {
			// Removes the resources with no ID or empty
			try {
				if (elem.evaluate("//ID").get(0) != null && elem.evaluate("//ID").get(0).trim().length() > 0) {
					retval.add(elem.toString());
				} else {
					_log.debug("*** Found an invalid element with no ID");
				}
			} catch (Exception e) {
				_log.debug("[getResourcesByType] found a resource with empty ID");
			}
		}
		return retval;
	}
	/**
	 * this method used to read the MAXWAIT param from the resourcemanagement.properties files, currently it reads it from the static var defined on top of this class
	 * TODO: Make it configurable again from a property file
	 * @param queryScope
	 * @return
	 */
	public ArrayList<String> getExpiredGHNs(final GCUBEScope queryScope) {
		try {
			return applyQuery(
					queryScope,
					QueryLocation.SWEEPER_EXPIRED_GHN,
					new QueryParameter("MAXWAIT", LIVE_GHN_MAX_MINUTES));
		} catch (Exception e) {
			_log.error(e.getMessage());
			return null;
		}
	}
	public ArrayList<String> getDeadGHNs(GCUBEScope queryScope) {
		try {
			return applyQuery(
					queryScope,
					QueryLocation.SWEEPER_DEAD_GHN);
		} catch (Exception e) {
			_log.error(e.getMessage());
			return null;
		}
	}

	public ArrayList<String> getOrphanRI(GCUBEScope queryScope) {
		try {
			return applyQuery(
					queryScope,
					QueryLocation.SWEEPER_ORPHAN_RI);
		} catch (Exception e) {
			_log.error(e.getMessage());
			return null;
		}
	}

	@SuppressWarnings("deprecation")
	public void applySweep(GCUBEScope queryScope, List<ModelData> elems) {
		for (ModelData entry : elems) {
			try {
				SweeperActions action = SweeperActions.valueOf(((Object) entry.get("Actions")).toString());
				String resID = ((Object) entry.get("ID")).toString();

				_log.info("Cleaning up " + resID + " " + action);

				switch(action) {
				case APPLY_GHN_DELETE:
					new GHNManager(resID).forceDelete(queryScope);
					break;
				case APPLY_GHN_MOVE_TO_UNREACHABLE:
					GHNManager ghnManager = new GHNManager(resID);
					GCUBEHostingNode res = (GCUBEHostingNode) ghnManager.getGCUBEResource(queryScope);
					res.getNodeDescription().setStatus(Status.UNREACHABLE);
					ghnManager.getISPublisher().updateGCUBEResource(res, queryScope, ghnManager.getSecurityManager());
					break;
				case APPLY_RI_DELETE:
					RunningInstanceManager riManager = new RunningInstanceManager(resID);
					_log.trace("*** The running instance " + resID + " will be deleted");
					riManager.forceDelete(queryScope);
					break;
				default:
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
