package flow;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.avaya.ingensg.ce.wa.imrest.common.model.MetricsResponse;
import com.avaya.ingensg.ce.wa.imrest.common.model.ServiceMetricsResponse;
import com.avaya.sce.runtime.tracking.ReportInfo;
import com.avaya.sce.runtimecommon.IReportInfo;
import flow.constants.SSAConstants;
import flow.utils.Utils;

/**
 * A basic servlet which allows a user to define their code, generate any
 * output, and to select where to transition to next. Last generated by
 * Orchestration Designer at: (timestamp generation disabled)
 */
public class ParseMetricsResponse extends com.avaya.sce.runtime.BasicServlet {

	// {{START:CLASS:FIELDS
	// }}END:CLCheckEWT

	/**
	 * Default constructor Last generated by Orchestration Designer at:
	 * (timestamp generation disabled)
	 */
	public ParseMetricsResponse() {
		// {{START:CLASS:CONSTRUCTOR
		super();
		// }}END:CLASS:CONSTRUCTOR
	}

	/**
	 * CheckEWT allows for custom integration with other Java components. You
	 * may use Java for sophisticated logic or to integrate with custom
	 * connectors (i.e. JMS, custom web services, sockets, XML, JAXB, etc.)
	 * 
	 * Any custom code added here should work as efficiently as possible to
	 * prevent delays. It's important to design your callflow so that the voice
	 * browser (Voice Portal/IR) is not waiting too long for a response as this
	 * can lead to a poor caller experience. Additionally, if the response to
	 * the client voice browser exceeds the configured timeout, the platform may
	 * throw an "error.badfetch".
	 * 
	 * Using this method, you have access to all session variables through the
	 * SCESession object.
	 * 
	 * The code generator will *** NOT *** overwrite this method in the future.
	 * Last generated by Orchestration Designer at: (timestamp generation
	 * disabled)
	 */
	public void servletImplementation(com.avaya.sce.runtimecommon.SCESession mySession) {

		Map<String, String> metrics = null;

		String obj = (String) mySession.getVariableField(IProjectVariables.SERVICE_METRICS_RESPONSE).getObjectValue();
		Utils.logInfo("Returned Service Metrics: " + obj, mySession);

		MetricsResponse metricsResponse = null;
		try {
			metricsResponse = Utils.extractMetricsResponse(obj, mySession);
		} catch (IOException ex) {
			ReportInfo report = new com.avaya.sce.runtime.tracking.ReportInfo(
					IReportInfo.REPORT_TYPE_PROGRESS, IReportInfo.ALARM_LEVEL_MAJOR,
					SSAConstants.REPORTING_TAG, "Failed to parse metrics response", ex.getMessage());
			report.trackItems(mySession);
			mySession.getVariableField(IProjectVariables.SERVICE_METRICS_RESPONSE).setValue(null);
			return;
		}

		// Can happen if e.g. WA is down or TCP timeout
		if (metricsResponse == null) {
			// If no metrics are available, then the service in question may not
			// have been created yet. In this case, default to -1.
			Utils.logInfo("No Metrics available for this service; staffed count is unknown.",
					mySession);
			Utils.setVariableField(IProjectVariables.METRICS_RESPONSE_SERVICE_1,
					IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_STAFFED_COUNT,
					String.valueOf(-1), mySession);
		} else {
			Map<Integer, ServiceMetricsResponse> mapMetricsResponse = metricsResponse
					.getServiceMetricsResponseMap();
			Iterator<Entry<Integer, ServiceMetricsResponse>> mapIterator = mapMetricsResponse
					.entrySet().iterator();

			while (mapIterator.hasNext()) {
				Map.Entry<Integer, ServiceMetricsResponse> serviceMetricsResponseObj = mapIterator
						.next();

				ServiceMetricsResponse value = serviceMetricsResponseObj.getValue();
				metrics = value.getMetrics();

				if (metrics == null) {
					// If no metrics are available, then the service in question
					// may not have been created yet. In this case, default to
					// -1.
					Utils.logInfo(
							"No Metrics available for this service; staffed count is unknown.",
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_STAFFED_COUNT,
							String.valueOf(-1), mySession);
				} else {
					Utils.setVariableField(IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_EWT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_EWT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_STAFFED_COUNT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_STAFFED_COUNT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_READY_COUNT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_READY_COUNT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_BUSY_COUNT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_RESOURCE_BUSY_COUNT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_PROCESSING_WORK_COUNT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_PROCESSING_WORK_COUNT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_WAITING_WORK_COUNT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_WAITING_WORK_COUNT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_COMPLETED_WORK_COUNT,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_COMPLETED_WORK_COUNT),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_OLDEST_WORK_WAITING,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_OLDEST_WORK_WAITING),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_SERVICE_OCCUPANCY,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_OLDEST_WORK_WAITING),
							mySession);
					Utils.setVariableField(
							IProjectVariables.METRICS_RESPONSE_SERVICE_1,
							IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_ROLLING_ASA,
							metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_ROLLING_ASA),
							mySession);
				}
			}
		}

		String ewt;
		if ((metrics != null)
				&& (metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_EWT) != null)) {
			ewt = (String) metrics.get(IProjectVariables.METRICS_RESPONSE_SERVICE_1_FIELD_EWT);
		} else {
			ewt = "n/a";
		}

		try {
			double ewtDouble = Math.ceil((Double.parseDouble(ewt)));
			int ewtInt = (int) ewtDouble;
			Utils.logInfo("EWT is a valid number (" + ewt + "). Will assign the rounded value: "
					+ ewtInt, mySession);
			Utils.setVariableField(IProjectVariables.EWT, IProjectVariables.EWT_FIELD_EWTROUNDED,
					String.valueOf(ewtInt), mySession);

		} catch (Exception e) {
			ReportInfo report = new com.avaya.sce.runtime.tracking.ReportInfo(
					IReportInfo.REPORT_TYPE_PROGRESS, IReportInfo.ALARM_LEVEL_INFO,
					SSAConstants.REPORTING_TAG, "EWT is NOT a valid number. Will set EWT to -1",
					e.getMessage());
			report.trackItems(mySession);
			Utils.setVariableField(IProjectVariables.EWT, IProjectVariables.EWT_FIELD_EWTROUNDED,
					String.valueOf(-1), mySession);
		}
	}

	/**
	 * Builds the list of branches that are defined for this servlet object.
	 * This list is built automatically by defining Goto nodes in the call flow editor.
	 * It is the programmer's responsibilty to provide at least one enabled Goto.<BR>
	 *
	 * The user should override updateBranches() to determine which Goto that the
	 * framework will activate.  If there is not at least one enabled Goto item, 
	 * the framework will throw a runtime exception.<BR>
	 *
	 * This method is generated automatically and changes to it may
	 * be overwritten next time code is generated.  To modify the list
	 * of branches for the flow item, override:
	 *     <code>updateBranches(Collection branches, SCESession mySession)</code>
	 *
	 * @return a Collection of <code>com.avaya.sce.runtime.Goto</code>
	 * objects that will be evaluated at runtime.  If there are no gotos
	 * defined in the Servlet node, then this returns null.
	 * Last generated by Orchestration Designer at: (timestamp generation disabled)
	 */
	public java.util.Collection getBranches(com.avaya.sce.runtimecommon.SCESession mySession) {
		java.util.List list = null;
		com.avaya.sce.runtime.Goto aGoto = null;
		list = new java.util.ArrayList(1);

		aGoto = new com.avaya.sce.runtime.Goto("CheckStaffedCount", 0, true, "Default");
		list.add(aGoto);

		return list;
	}
}
