/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © 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 java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;

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

/**
 * 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)
   */
  Override
  SuppressWarnings("unchecked")
  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)
   */
  Override
  SuppressWarnings("unchecked")
  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)
   */
  Override
  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)
   */
  Override
  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;
  }
}