/*
 * 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;

import java.util.ArrayList;
import java.util.EventListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Defines the a request for the purposes of interacting with the integration API.
 */
public class IntegrationRequest {
  /**
   * Models a listener interested in request status change events.
   */
  public interface StatusListener extends EventListener {
    void statusChanged(IntegrationRequest req);
  }

  /**
   * Lists the different status of a request.
   */
  public static class Status {
    public static final int UNKNOWN = -1;
    public static final int REQ_HANDLED = 0;
    public static final int REQ_FAILED = 1;
  }

  /**
   * Lists the different requests types.
   */
  public static class Type {
    public static final int UNKNOWN = -1;
    public static final int CONNECT_NETWORK_DATASOURCE = 0;
    public static final int CONNECT_INVENTORY_DATASOURCE = 1;
    public static final int CONNECT_SERVICES_DATASOURCE = 2;
    public static final int CONNECT_SERVICES_NETWORK_DATASOURCE = 3;
    public static final int QUERY_SERVICES_DETAIL_DATASOURCE = 4;
    public static final int DISCONNECT_NETWORK_DATASOURCE = 5;
    public static final int DISCONNECT_INVENTORY_DATASOURCE = 6;
    public static final int DISCONNECT_SERVICES_DATASOURCE = 7;
    public static final int DISCONNECT_SERVICE_NETWORK_DATASOURCE = 8;
    public static final int CONNECT_ALARM_MONITOR = 9;
    public static final int DISCONNECT_ALARM_MONITOR = 10;
    public static final int ACKNOWLEDGE_ALARMS = 11;
    public static final int UNACKNOWLEDGE_ALARMS = 12;
    public static final int RUNNABLE = 13;
  }

  /**
   * Keys used in the request parameters key-value map
   */
  public static class ParamKey {
    public static final String UNKNOWN = "unk";
    public static final String ALARMIDS_KEY = "aid";
    public static final String DATASOURCE_KEY = "dsk";
    public static final String EXTRA_KEY = "ext";
  }

  // request type
  private int requestType = -1;
  // requester (client) identifier
  private String systemId;
  // request operator identifier
  private String userId;
  // key-value map parameters
  private Map<String,Object> requestParams = null;
  // list of statusListeners
  private List<StatusListener> statusListeners = null;
  // The status of the request
  private int requestStatus = Status.UNKNOWN;

  /**
   * Creates a new request of the given type.
   * 
   * @param type    The request type
   * @param sysId   The system identifier
   * @param usrId   The user identifier
   * @param params  The request parameters
   */
  public IntegrationRequest(int type, String sysId, String usrId, Map<String,Object> params) {
    requestType = type;
    systemId = sysId;
    userId = usrId;
    requestParams = new HashMap<String,Object>(params);
  }

  /**
   * Accesses the request type.
   * 
   * @return  The request type
   */
  public int getType() {
    return requestType;
  }

  /**
   * Accesses the system id of the requester.
   * 
   * @return  The system identifier.
   */
  public String getSystemId() {
    return systemId;
  }

  /**
   * Accesses the user id of the requester.
   * 
   * @return  The user identifier.
   */
  public String getUserId() {
    return userId;
  }

  /**
   * Accesses the request parameters.
   * 
   * @return The unmodifiable map of key-value parameters
   */
  public Map<String,Object> getParameters() {
    return requestParams;
  }

  /**
   * Adds the status listener for this request.
   * 
   * @param listener  The status listener to be added
   */
  public synchronized void addStatusListener(StatusListener listener) {
    if (null == statusListeners) {
      statusListeners = new ArrayList<StatusListener>();
    }
    statusListeners.add(listener);
  }

  /**
   * Removes a status listener from this request.
   * 
   * @param listener  The status listener to be removed
   */
  public synchronized void removeStatusListener(StatusListener listener) {
    if (null != statusListeners) {
      statusListeners.remove(listener);
    }
  }

  /**
   * Accesses the request status.
   * 
   * @return  The currrent request status
   */
  public synchronized int getStatus() {
    return requestStatus;
  }

  /**
   * Sets the current status. All status listeners will
   * be notified of a status change.
   * 
   * @param status The actual request status
   */
  public synchronized void setStatus(int status) {
    if (requestStatus == status) {
      return;
    }
    requestStatus = status;
    if (null != statusListeners) {
      for (int ii = 0; ii < statusListeners.size(); ii++) {
        (statusListeners.get(ii)).statusChanged(IntegrationRequest.this);
      }
    }
  }
}