/*
 * 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.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A request dispatcher used to interface with a given backend system.
 */
public class IntegrationDispatcher {

  // The logger to be used
  private Logger iLogger;

  // The system identifier generated
  private String systemId;

  /**
   * Request handler used to interact with the backend system.  
   */
  private RequestHandler requestHandler;

  /**
   * Creates a new dispatcher. Note that this dispatcher can only be used to 
   * connect after an <code>RequestHandler</code> has been associated 
   * with it.
   * 
   * @param logger  The logger to be used by this dispatcher.
   */
  public IntegrationDispatcher(Logger logger) {
    iLogger = logger;
    iLogger.log(Level.FINE, "Constructing request dispatcher");
  }

  /**
   * Connects the request dispatcher.
   * <p>
   * This method will connect the dispatcher with the backend (request handler) 
   * and process with system registration.
   * <p>
   * Note that this dispatcher can only be used to 
   * connect after an <code>RequestHandler</code> has been associated 
   * with it.
   * 
   * @param systemIdPrefix  The desired prefix for the unique
   *                        system identifier.
   * @return The unique system identifier generated by the 
   *         back-end.
   */
  public String connect(String systemIdPrefix) {
    iLogger.log(Level.FINE, "Connecting client to the back end");

    // Access the singleton, it might be initialized here
    systemId = requestHandler.registerClientSystem(systemIdPrefix);
    iLogger.log(Level.FINE, "Client successfully connected to the back end");

    return systemId;
  }

  /**
   * Disconnects the request dispatcher.
   * This method will disconnect the dispatcher from the backend system,
   * unregistering its unique system identification.
   */
  public void disconnect() {
    iLogger.log(Level.FINE, "Disconnecting client from the back end");
    requestHandler.unregisterClientSystem(systemId);
    iLogger.log(Level.FINE, "Client disconnected");
  }

  /**
   * Dispatch a request to the back-end.
   *
   * @param type     The type of the request being dispatched
   * @param userId   The user identifier dispatching the request
   * @param params   The request parameters to be dispatched
   * @param listener The listener to be notified of dispatch results
   */
  public synchronized void dispatch(int type, String userId, Map<String,Object> params,
      IntegrationRequest.StatusListener listener) {
    Integer typeInt = new Integer(type);
    iLogger.log(
        Level.FINE, "Dispatching request type {0} to the back end", typeInt);

    IntegrationRequest newRequest = 
      new IntegrationRequest(type, systemId, userId, params);

    if (null != listener) {
      newRequest.addStatusListener(listener);
    }
    requestHandler.addRequest(newRequest);
    iLogger.log(Level.FINE, "Request type {0} dispatched", typeInt);
  }

  /**
   * Returns the <code>RequestHandler</code> associated with this dispatcher.
   */
  public RequestHandler getRequestHandler() {
    return requestHandler;
  }

  /**
   * Sets the <code>RequestHandler</code> associated with this dispatcher.
   */
  public void setRequestHandler(RequestHandler requestHandler) {
    this.requestHandler = requestHandler;
  }
}