/**
 * 
 */
package astri.test.testMasterCompImpl;

import java.sql.Timestamp;

import alma.ACS.MasterComponentImpl.MasterComponentImplBase;
import alma.ACS.MasterComponentImpl.statemachine.AlmaSubsystemActions;
import alma.ACS.MasterComponentPackage.SubsystemStateEvent;
import alma.acs.genfw.runtime.sm.AcsStateActionException;
import alma.alarmsystem.source.ACSAlarmSystemInterface;
import alma.alarmsystem.source.ACSAlarmSystemInterfaceFactory;
import alma.alarmsystem.source.ACSFaultState;
import astri.test.testComp1;
import astri.test.testComp1Helper;
import astri.test.testMasterCompOperations;
import astri.test.testPingComp1;
import astri.test.testPingComp1Helper;

/**
 * @author astrisw
 *
 */
public class testMasterCompImpl extends MasterComponentImplBase
		implements testMasterCompOperations, AlmaSubsystemActions {

	/* (non-Javadoc)
	 * @see alma.ACS.MasterComponentImpl.statemachine.AlmaSubsystemActions#initSubsysPass1()
	 */
	private static String testComp1Name = "testPingComp1";
	testPingComp1 comp1 = null;
	@Override
	public void initSubsysPass1() throws AcsStateActionException {
		
			try {
				m_logger.fine("PASS1: connecting to " + testComp1Name);
				comp1 = testPingComp1Helper.narrow(m_containerServices.getComponent(testComp1Name));
				m_logger.info("PASS1 Inizializing component");
			} catch (Exception e) {
				throw new AcsStateActionException(e);
			}
			m_logger.fine("PASS1: monitor component");
			//monitorComponent(comp1,new testCompResourceErrorHandler<testPingComp1> (testComp1Name,true));
			monitorPingableResource(comp1, testComp1Name, new testCompResourceErrorHandler<testPingComp1> (testComp1Name,true));
	}

	/* (non-Javadoc)
	 * @see alma.ACS.MasterComponentImpl.statemachine.AlmaSubsystemActions#initSubsysPass2()
	 */
	@Override
	public void initSubsysPass2() throws AcsStateActionException {
		
		m_logger.info("Pass2");
	}

	/* (non-Javadoc)
	 * @see alma.ACS.MasterComponentImpl.statemachine.AlmaSubsystemActions#reinitSubsystem()
	 */
	@Override
	public void reinitSubsystem() throws AcsStateActionException {
		
		m_logger.info("Reinit");
		shutDownSubsysPass1();
		shutDownSubsysPass2();			
		
		try {
			comp1 = testPingComp1Helper.narrow(m_containerServices
					.getComponent(testComp1Name));
		} catch (Throwable e) {
			m_logger.severe("Could not reinit subsystem: "+e.toString());
			throw new AcsStateActionException(e);
		}
		
		/* Now init  components: */

		initSubsysPass1();
		initSubsysPass2();

	}

	/* (non-Javadoc)
	 * @see alma.ACS.MasterComponentImpl.statemachine.AlmaSubsystemActions#shutDownSubsysPass1()
	 */
	@Override
	public void shutDownSubsysPass1() throws AcsStateActionException {

		m_logger.info("ShutDown1");
		stopMonitoringAllResources();
	}

	/* (non-Javadoc)
	 * @see alma.ACS.MasterComponentImpl.statemachine.AlmaSubsystemActions#shutDownSubsysPass2()
	 */
	@Override
	public void shutDownSubsysPass2() throws AcsStateActionException {
		
		m_logger.info("ShutDown2");
		m_containerServices.releaseComponent(testComp1Name);
	}

	/* (non-Javadoc)
	 * @see alma.ACS.MasterComponentImpl.MasterComponentImplBase#getActionHandler()
	 */
	@Override
	protected AlmaSubsystemActions getActionHandler() {
		
		return this;
	}
	
	
	
	
	
	
	protected class testCompResourceErrorHandler<T> extends DefaultResourceErrorHandler<T> {

		testCompResourceErrorHandler(String resourceName, boolean isComponent) {
			super(resourceName, isComponent);
		}
		

		@Override
		public boolean resourceUnreachable(T resource) {
			
			super.resourceUnreachable(resource);
			send_alarm(resourceName, true);
			return true;
		}

		@Override
		public void badState(T resource, String stateName) {
			
			super.badState(resource, stateName);
			//m_logger.severe("YYY Sending alarm (bad state): "+resourceName);
			send_alarm(resourceName, true);
		}

		@Override
		public void resourceRecovered(T resource) {

			try {
				m_logger.info((isComponent ? "Component" : "Resource") + " '"
						+ resourceName
						+ "' has recoveres, will REINIT subsystem.");
				doTransition(SubsystemStateEvent.SUBSYSEVENT_REINIT);
				
				send_alarm(resourceName, false);
			} catch (Throwable thr) {
				m_logger.warning(
						"exception caught while REINITing subsystem." +thr.toString());
			}
			
		}
		
		protected void send_alarm(String faultMember, boolean active) {
			String faultFamily = "testMastC";
			int faultCode = 1;
			String faultState;
			if (active) {
				faultState = ACSFaultState.ACTIVE;
			} else {
				faultState=ACSFaultState.TERMINATE;
			}
			send_alarm(faultFamily, faultMember, faultCode, faultState);
		}
		
		protected void send_alarm(String faultFamily, String faultMember,
				int faultCode, String faultState) {
			try {
				ACSAlarmSystemInterface alarmSource = ACSAlarmSystemInterfaceFactory
						.createSource("TESTMASTERCOMP");
				ACSFaultState fs = ACSAlarmSystemInterfaceFactory.createFaultState(
						faultFamily, faultMember, faultCode);
				fs.setDescriptor(faultState);
				fs.setUserTimestamp(new Timestamp(System.currentTimeMillis()));

		
				alarmSource.push(fs);

			} catch (Exception e) {
				m_logger.warning("Failure when sending alarm: " + e);
				// throw new ArchiveEception(e.toString());
			}
		}
	}

	
}
