/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package integration.impl;

import ilog.cpl.datasource.IlpDefaultDataSource;
import ilog.cpl.model.IlpObject;
import ilog.tgo.model.IltAlarm;
import integration.IntegrationRequest;

import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;

/**
 * Implementation of a <code>RequestHandler</code> that provides an integration 
 * path to the TGO backend system composed solely of <code>IlpDataSource</code>
 * implementations. 
 * <p>
 * This implementation has the limitation that it assumes that all alarm related 
 * requests (acknowledge, unacknowledge...) are targeted at the same alarm data 
 * source. The alarm data source used is the one that is provided in the first 
 * <code>Connect Alarm Monitor</code> request. The binding to a new alarm data source 
 * can be done by issuing a <code>Disconnect Alarm Monitor</code> request followed by a 
 * <code>Connect Alarm Monitor</code> request 
 */
public class IntegrationRequestHandler extends AbstractRequestHandler {

  /**
   * Data source that contains the alarms.
   */
  private IlpDefaultDataSource alarmDataSource;
  
  /**
   * Implementation for a TGO backend system.
   * 
   * @see integration.impl.AbstractRequestHandler#handleAcknowledgeAlarms(java.lang.String, java.lang.String, java.util.Map)
   */
  protected synchronized boolean handleAcknowledgeAlarms(String systemId, String userId, Map<String,Object> params) {

    getLogger().log(Level.FINE, "Handling acknowledgement of alarms for user {0}", userId);
    Collection<Object> alarmIds = null;
    boolean ret = true;
    try {
      // Get alarmids
      alarmIds = (Collection<Object>)params.get(IntegrationRequest.ParamKey.ALARMIDS_KEY);

      Date time = new Date();

      for (Object alarmId : alarmIds) {
        IlpObject object = alarmDataSource.getObject(alarmId);

        if (object instanceof IltAlarm) {
          IltAlarm alarm = (IltAlarm) object;
          alarm.setAlarmAckState(true);
          alarm.setAckSystemId(systemId);
          alarm.setAckUserId(userId);
          alarm.setAckTime(time);
          alarm.setAlarmChangedTime(time);          
        }        
      }
    } catch (Exception x) {
      getLogger().log(Level.WARNING,
          "Exception caught while acknowledging alarms: {0}", x.getLocalizedMessage());
      ret = false;
    }
    getLogger().log(Level.FINE, "Alarm acknowledging successfully handled");
    return ret;
  }

  /**
   * Implementation for a TGO backend system.
   * 
   * @see integration.impl.AbstractRequestHandler#handleUnacknowledgeAlarms(java.lang.String, java.lang.String, java.util.Map)
   */
  protected synchronized boolean handleUnacknowledgeAlarms(String systemId, String userId, Map<String,Object> params) {

    getLogger().log(Level.FINE, "Handling unacknowledgement of alarms for user {0}", userId);
    Collection<Object> alarmIds = null;
    boolean ret = true;
    try {

      // Get data source, alarmids and userid
      alarmIds = (Collection<Object>)params.get(IntegrationRequest.ParamKey.ALARMIDS_KEY);

      Date time = new Date();

      for (Object alarmId : alarmIds) {
        IlpObject object = alarmDataSource.getObject(alarmId);

        if (object instanceof IltAlarm) {
          IltAlarm alarm = (IltAlarm) object;
          alarm.setAlarmAckState(false);
          alarm.setAlarmChangedTime(time);  
        }        
      }
    } catch (Exception x) {
      getLogger().log(Level.WARNING,
          "Exception caught while unacknowledging alarms: {0}", x.getLocalizedMessage());
      ret = false;
    }
    getLogger().log(Level.FINE, "Alarm unacknowledging successfully handled");
    return ret;
  }

  /**
   * Implementation for a TGO backend system.
   * 
   * @see integration.impl.AbstractRequestHandler#handleConnectAlarmMonitor(java.lang.String, java.util.Map)
   */
  protected synchronized boolean handleConnectAlarmMonitor(String systemId, Map<String,Object> params) {
    getLogger().log(Level.FINE, "Handling subscription");
    try {
      // Get data source
      alarmDataSource = (IlpDefaultDataSource)params.get(IntegrationRequest.ParamKey.DATASOURCE_KEY);

    } catch (Exception x) {
      getLogger().log(Level.WARNING,
          "Exception caught while subscribing to data source: {0}",
          x.getLocalizedMessage());
      return false;
    }    
    getLogger().log(Level.FINE,
    "Data source successfully subscribed to");
    return true;
  }

  /**
   * Implementation for a TGO backend system.
   * 
   * @see integration.impl.AbstractRequestHandler#handleDisconnectAlarmMonitor(java.lang.String, java.util.Map)
   */
  protected synchronized boolean handleDisconnectAlarmMonitor(String systemId, Map<String,Object> params) {
    getLogger().log(Level.FINE, "Handling unsubscription");
    try {
      alarmDataSource.clear();      
      alarmDataSource = null;
    } catch (Exception x) {
      getLogger().log(Level.WARNING,
          "Exception caught while unsubscribing data source: {0}",
          x.getLocalizedMessage());
      return false;
    }
    getLogger().log(Level.FINE, "Data source unsubscription successfully handled");
    return true;
  }
}