package flow;

import java.util.HashMap;
import java.util.Map;

import com.avaya.sce.runtime.tracking.ReportInfo;
import com.avaya.sce.runtimecommon.IReportInfo;

import flow.constants.SSAConstants;
import flow.pojo.Attribute;
import flow.pojo.AttributeValue;
import flow.pojo.SelfService;
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 Dialog Designer at: 2012-JUN-14  12:09:54 PM
 */
public class LoadConfigurationData extends com.avaya.sce.runtime.BasicServlet {

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

	/**
	 * Default constructor
	 * Last generated by Dialog Designer at: 2012-JUN-14  12:09:54 PM
	 */
	public LoadConfigurationData() {
		//{{START:CLASS:CONSTRUCTOR
		super();
		//}}END:CLASS:CONSTRUCTOR
	}

	/**
	 * This method 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 Dialog Designer at: 2012-JUN-14  12:09:54 PM
	 */
	public void servletImplementation(com.avaya.sce.runtimecommon.SCESession session) {

		try {
			// Read attribute XML file
			final SelfService selfServiceData = Utils.getConfigurationData(this.getServletContext(), session);
					
			// Create a map for "Attribute Category" -> Attribute Object
			Map<String, Attribute> attributesMap = new HashMap<String, Attribute>();
			for(Attribute attr : selfServiceData.getAttributes()){
				attributesMap.put(attr.getCategory(), attr);
			}
			Utils.logInfo(attributesMap.size() + " Categories imported successfully", session);
			
			//Set EWT limit
			Utils.setVariableField(IProjectVariables.EWT, IProjectVariables.EWT_FIELD_EWTLIMIT, selfServiceData.getEwtLimit(), session);

			//Set Categories for the menu prompts and service map
            Utils.setVariableField(IProjectVariables.MENU_CATEGORIES, IProjectVariables.MENU_CATEGORIES_FIELD_MENU_1CATEGORY, selfServiceData.getMenu1Category(), session);
            Utils.setVariableField(IProjectVariables.MENU_CATEGORIES, IProjectVariables.MENU_CATEGORIES_FIELD_MENU_2CATEGORY, selfServiceData.getMenu2Category(), session);
            Utils.setVariableField(IProjectVariables.SAMPLE_CATEGORY, selfServiceData.getServiceMapCategory(), session);
            Utils.logInfo("Menu1 Category: [" + selfServiceData.getMenu1Category() + "]", session);
            Utils.logInfo("Menu2 Category: [" + selfServiceData.getMenu2Category() + "]", session);
            Utils.logInfo("ServiceMap Category: [" + selfServiceData.getServiceMapCategory() + "]", session);
            
			//Build menu prompt using first Menu item from attribute XML e.g. Service
            String menu1Category = (String)Utils.getVariableField(IProjectVariables.PROMPTS, IProjectVariables.PROMPTS_FIELD_ASK_MENU_1, session).replaceAll(SSAConstants.CATEGORY_TOKEN, selfServiceData.getMenu1Category());            
			int menu1OptionsLength = attributesMap.get(selfServiceData.getMenu1Category()).getValues().size();
			StringBuilder menu1Text = buildMenuText(selfServiceData.getMenu1Category(), attributesMap);
			Utils.setVariableField(IProjectVariables.PROMPTS, IProjectVariables.PROMPTS_FIELD_ASK_MENU_1, menu1Category, session);			
			Utils.setVariableField(IProjectVariables.PROMPTS, IProjectVariables.PROMPTS_FIELD_SELECT_MENU_1, menu1Text.toString(), session);
			Utils.setVariableField(IProjectVariables.FIRST_MENU_SELECTION, IProjectVariables.FIRST_MENU_SELECTION_FIELD_SIZE, menu1OptionsLength, session);
			
			//Build menu prompt using second Menu item from attributes XML e.g. Language
            String menu2Category = (String)Utils.getVariableField(IProjectVariables.PROMPTS, IProjectVariables.PROMPTS_FIELD_ASK_MENU_2, session).replaceAll(SSAConstants.CATEGORY_TOKEN, selfServiceData.getMenu2Category());			
			int menu2OptionsLength = attributesMap.get(selfServiceData.getMenu2Category()).getValues().size();
			StringBuilder menu2Text = buildMenuText(selfServiceData.getMenu2Category(), attributesMap);
			Utils.setVariableField(IProjectVariables.PROMPTS, IProjectVariables.PROMPTS_FIELD_ASK_MENU_2, menu2Category, session);
			Utils.setVariableField(IProjectVariables.PROMPTS, IProjectVariables.PROMPTS_FIELD_SELECT_MENU_2, menu2Text.toString(), session);
			Utils.setVariableField(IProjectVariables.SECOND_MENU_SELECTION, IProjectVariables.SECOND_MENU_SELECTION_FIELD_SIZE, menu2OptionsLength, session);
								
			//Save attributes for later
			Utils.setVariableField(IProjectVariables.ATTRIBUTES, attributesMap, session);

		} catch (Exception e) {
			Utils.setVariableField(IProjectVariables.RESULT, "exit", session);
			ReportInfo exceptionreport = new ReportInfo( IReportInfo.REPORT_TYPE_PROGRESS, IReportInfo.ALARM_LEVEL_MAJOR, SSAConstants.REPORTING_TAG, "Error occurred: ", e.getMessage()); 
			exceptionreport.trackItems(session); 
			Utils.logInfo("Error occurred: " +  e.getMessage(), session);
		}
	}

	private StringBuilder buildMenuText(final String attrCategory,
		Map<String, Attribute> attributesMap) {
		
		StringBuilder menuText = new StringBuilder();
		int i = 1;
		int max = attributesMap.get(attrCategory).getValues().size();
		menuText.append("Press ");
		if(attributesMap.get(attrCategory) != null){
			for(AttributeValue values: attributesMap.get(attrCategory).getValues()){
				menuText.append(((i > 1) ? ((i == max) ? ", or " : ", ") : "") + i + " for " + values.getAlias());
				i++;
			}
		}
		menuText.append(".");
		return menuText;
	}

	
	/**
	 * 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("Welcome", 0, true, "Default");
		list.add(aGoto);

		return list;
	}
}
