/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.financial.view.rest;

import java.net.URI;
import java.util.concurrent.ScheduledExecutorService;

import javax.jms.ConnectionFactory;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.engine.marketdata.LiveMarketDataSourceRegistry;
import com.opengamma.engine.view.ViewDefinitionRepository;
import com.opengamma.engine.view.ViewProcess;
import com.opengamma.engine.view.ViewProcessor;
import com.opengamma.engine.view.calc.EngineResourceManager;
import com.opengamma.engine.view.calc.ViewCycle;
import com.opengamma.engine.view.client.ViewClient;
import com.opengamma.id.UniqueId;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
import com.opengamma.util.rest.FudgeRestClient;
import com.sun.jersey.api.client.ClientResponse;

/**
 * Provides access to a remote {@link ViewProcessor}.
 */
public class RemoteViewProcessor implements ViewProcessor {

  private final URI _baseUri;
  private final ScheduledExecutorService _scheduler;
  private final FudgeRestClient _client;
  private final ConnectionFactory _connectionFactory;
  
  public RemoteViewProcessor(URI baseUri, ConnectionFactory connectionFactory, ScheduledExecutorService scheduler) {
    _baseUri = baseUri;
    _scheduler = scheduler;
    _client = FudgeRestClient.create();
    _connectionFactory = connectionFactory;
  }

  @Override
  public UniqueId getUniqueId() {
    URI uri = UriBuilder.fromUri(_baseUri).path(DataViewProcessorResource.PATH_UNIQUE_ID).build();
    return _client.access(uri).get(UniqueId.class);
  }

  @Override
  public ViewDefinitionRepository getViewDefinitionRepository() {
    URI uri = UriBuilder.fromUri(_baseUri).path(DataViewProcessorResource.PATH_DEFINITION_REPOSITORY).build();
    return new RemoteViewDefinitionRepository(uri);
  }

  @Override
  public LiveMarketDataSourceRegistry getLiveMarketDataSourceRegistry() {
    URI uri = UriBuilder.fromUri(_baseUri).path(DataViewProcessorResource.PATH_LIVE_DATA_SOURCE_REGISTRY).build();
    return new RemoteLiveMarketDataSourceRegistry(uri);
  }
  
  //-------------------------------------------------------------------------
  @Override
  public ViewProcess getViewProcess(UniqueId viewProcessId) {
    URI uri = DataViewProcessorResource.uriViewProcess(_baseUri, viewProcessId);
    return new RemoteViewProcess(uri);
  }

  //-------------------------------------------------------------------------
  @Override
  public RemoteViewClient createViewClient(UserPrincipal clientUser) {
    URI uri = UriBuilder.fromUri(_baseUri).path(DataViewProcessorResource.PATH_CLIENTS).build();
    ClientResponse response = _client.access(uri).post(ClientResponse.class, clientUser);
    if (response.getStatus() != Status.CREATED.getStatusCode()) {
      throw new OpenGammaRuntimeException("Could not create view client: " + response);
    }
    URI clientLocation = response.getLocation();
    return new RemoteViewClient(this, clientLocation, OpenGammaFudgeContext.getInstance(), _connectionFactory, _scheduler);
  }

  @Override
  public ViewClient getViewClient(UniqueId clientId) {
    URI clientsBaseUri = UriBuilder.fromUri(_baseUri).path(DataViewProcessorResource.PATH_CLIENTS).build();
    URI clientUri = DataViewProcessorResource.uriClient(clientsBaseUri, clientId);
    return new RemoteViewClient(this, clientUri, OpenGammaFudgeContext.getInstance(), _connectionFactory, _scheduler);
  }

  //-------------------------------------------------------------------------
  @Override
  public EngineResourceManager<ViewCycle> getViewCycleManager() {
    URI uri = UriBuilder.fromUri(_baseUri).path(DataViewProcessorResource.PATH_CYCLES).build();
    return new RemoteViewCycleManager(uri, _scheduler);
  }

}

@@ -1227,17 +1227,26 @@
 ervice _
-s
+heartbeatS
 cheduler
@@ -1345,16 +1345,289 @@
 ory;%0A  %0A
+  /**%0A   * Constructs an instance.%0A   * %0A   * @param baseUri  the base URI of the remote view processor%0A   * @param connectionFactory  the JMS connection factory%0A   * @param heartbeatScheduler  the scheduler to be used to send heartbeats to the remote view processor%0A   */%0A
   public
@@ -1722,17 +1722,26 @@
 Service 
-s
+heartbeatS
 cheduler
@@ -1773,17 +1773,26 @@
 i;%0A    _
-s
+heartbeatS
 cheduler
@@ -1794,17 +1794,26 @@
 duler = 
-s
+heartbeatS
 cheduler
@@ -3553,33 +3553,42 @@
 ectionFactory, _
-s
+heartbeatS
 cheduler);%0A  %7D%0A%0A
@@ -3952,17 +3952,26 @@
 ctory, _
-s
+heartbeatS
 cheduler
@@ -4274,17 +4274,26 @@
 r(uri, _
-s
+heartbeatS
 cheduler

Rename scheduler to heartbeatScheduler for clarity