/*<copyright                                                          */
/* notice="cics-rm-source-program"                                    */
/* pids="CA0U"                                                        */
/* years="2014,2015"                                                  */
/* crc="4008609247" >                                                 */
/* 	Licensed Materials - Property of IBM                              */
/* 	"Restricted Materials of IBM"                                     */
/* 	CA0U                                                              */
/* 	(C) Copyright IBM Corp. 2014, 2015                                */
/* 	US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/* </copyright>                                                       */
package com.ibm.cics.ucd.steps;

import com.ibm.cics.ucd.JuliToLog4jHandler;
import static com.ibm.cics.ucd.StepLogHelper.printStepLog
import com.urbancode.air.AirPluginTool;

import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.logging.Handler;
import java.util.logging.Level;

import com.google.gson.Gson;

abstract class Step {
// <copyright 
// notice="cics-rm-source-program" 
// pids="CA0U" 
// years="2014,2015" 
// crc="1569743332" > 
// 	Licensed Materials - Property of IBM 
// 	"Restricted Materials of IBM" 
// 	CA0U 
// 	(C) Copyright IBM Corp. 2014, 2015 
// 	US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
// </copyright> 
	
	protected AirPluginTool apTool;
	protected List<Map<String,Object>> errorList;
	
	// Hold the Logger to avoid garbage-collection
	private Logger comIbmCicsLogger;
	private Handler activeHandler;
	private static final String stepEntry = "STEP ENTRY >"; //$NON-NLS-1$
	private static final String stepExit = "STEP EXIT <"; //$NON-NLS-1$

	public Step(String inputPropertyFile, String outputPropertyFile) {
		apTool = new AirPluginTool(inputPropertyFile, outputPropertyFile);
	}

	/*
	 * Constructor for unit testing
	 */
	Step(AirPluginTool apTool) {
		this.apTool = apTool;
	}

	public void log(String msg) {
		printStepLog(msg);
	}
	
	public void logTrace(Level level, String sourceClass, String sourceMethod, String msg) {
		comIbmCicsLogger.logp(level, sourceClass, sourceMethod, msg)
	}
	public void logTrace(Level level, String sourceClass, String sourceMethod, String msg, Object param1) {
		comIbmCicsLogger.logp(level, sourceClass, sourceMethod, msg, param1)
	}
	
	public void logTrace(Level level, String sourceClass, String sourceMethod, String msg, Object[] params) {
		comIbmCicsLogger.logp(level, sourceClass, sourceMethod, msg, params)
	}
	public void before() {
		errorList = new ArrayList<Map<String,Object>>();
		
		Logger rootLogger = LogManager.getLogManager().getLogger("");
		// Remove any old handlers
		for (Handler handler : rootLogger.getHandlers()) {
			rootLogger.removeHandler(handler);
		}
		
		// Create our own logger
		comIbmCicsLogger = Logger.getLogger("com.ibm.cics");
		comIbmCicsLogger.setUseParentHandlers(false);
		
		// Pass all events on
		Level handlerLevel = Level.ALL;
		Level rootLevel = Level.ALL;
		
		// Add our own handler to JUL
		activeHandler = new JuliToLog4jHandler();
		activeHandler.setLevel(handlerLevel);
		comIbmCicsLogger.addHandler(activeHandler);
		rootLogger.setLevel(rootLevel);
	}

	public void after() {
		comIbmCicsLogger.removeHandler(activeHandler)
		
		Gson errorJSON = new Gson();
		apTool.setOutputProperty("cics.response.errors",errorJSON.toJson(errorList));
		apTool.storeOutputProperties();
	}
	
	protected abstract void runStep();
	
	public void run() throws Exception {
		try {
			before();
			logTrace(Level.INFO, this.class.getName(), "run", stepEntry)
			
			runStep();
			
			logTrace(Level.INFO, this.class.getName(), "run", stepExit)
		} finally {
			after();
		}
	}
	
}
