/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.shell.remoteui;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.HelpInfo;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.dev.protobuf.ByteString;
import com.google.gwt.dev.shell.remoteui.MessageTransport.RequestException;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Request;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Response;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Request.ViewerRequest;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Request.ViewerRequest.LogData;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Request.ViewerRequest.RequestType;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Response.ViewerResponse;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Response.ViewerResponse.CapabilityExchange.Capability;
import com.google.gwt.dev.util.Callback;
import com.google.gwt.dev.util.log.AbstractTreeLogger;

import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * Used for making requests to a remote ViewerService server.
 * 
 * TODO: If this becomes part of the public API, we'll need to provide a level
 * of indirection in front of the protobuf classes; We're going to be rebasing
 * the protobuf library, and we don't want to expose the rebased API as public.
 */
public class ViewerServiceClient {

  private final MessageTransport transport;
  private final TreeLogger unexpectedErrorLogger;

  /**
   * Create a new instance.
   * 
   * @param processor A MessageProcessor that is used to communicate with the
   *          ViewerService server.
   */
  public ViewerServiceClient(MessageTransport processor,
      TreeLogger unexpectedErrorLogger) {
    this.transport = processor;
    this.unexpectedErrorLogger = unexpectedErrorLogger;
  }

  /**
   * Add an entry that also serves as a log branch.
   * 
   * @param indexInParent The index of this entry/branch within the parent
   *          logger
   * @param type The severity of the log message.
   * @param msg The message.
   * @param caught An exception associated with the message
   * @param helpInfo A URL or message which directs the user to helpful
   *          information related to the log message
   * @param parentLogHandle The log handle of the parent of this log
   *          entry/branch
   * @param callback the callback to call when a branch handle is available
   */
  public void addLogBranch(int indexInParent, Type type, String msg,
      Throwable caught, HelpInfo helpInfo, int parentLogHandle,
      final Callback<Integer> callback) {

    LogData.Builder logDataBuilder = generateLogData(type, msg, caught,
        helpInfo);

    ViewerRequest.AddLogBranch.Builder addlogBranchBuilder = ViewerRequest.AddLogBranch.newBuilder();
    addlogBranchBuilder.setParentLogHandle(parentLogHandle);
    addlogBranchBuilder.setIndexInParent(indexInParent);
    addlogBranchBuilder.setLogData(logDataBuilder);

    ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
    viewerRequestBuilder.setRequestType(ViewerRequest.RequestType.ADD_LOG_BRANCH);
    viewerRequestBuilder.setAddLogBranch(addlogBranchBuilder);

    Request requestMessage = buildRequestMessageFromViewerRequest(
        viewerRequestBuilder).build();

    transport.executeRequestAsync(requestMessage, new Callback<Response>() {
      public void onDone(Response result) {
        callback.onDone(result.getViewerResponse().getAddLogBranch().getLogHandle());
      }

      public void onError(Throwable t) {
        callback.onError(t);
      }
    });
  }

  /**
   * Add a log entry.
   * 
   * @param indexInParent The index of this entry within the parent logger
   * @param type The severity of the log message.
   * @param msg The message.
   * @param caught An exception associated with the message
   * @param helpInfo A URL or message which directs the user to helpful
   *          information related to the log message
   * @param logHandle The log handle of the parent of this log entry/branch
   */
  public void addLogEntry(int indexInParent, Type type, String msg,
      Throwable caught, HelpInfo helpInfo, int logHandle) {
    LogData.Builder logDataBuilder = generateLogData(type, msg, caught,
        helpInfo);

    ViewerRequest.AddLogEntry.Builder addLogEntryBuilder = ViewerRequest.AddLogEntry.newBuilder();
    addLogEntryBuilder.setLogHandle(logHandle);
    addLogEntryBuilder.setIndexInLog(indexInParent);
    addLogEntryBuilder.setLogData(logDataBuilder);

    ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
    viewerRequestBuilder.setRequestType(ViewerRequest.RequestType.ADD_LOG_ENTRY);
    viewerRequestBuilder.setAddLogEntry(addLogEntryBuilder);

    Request requestMessage = buildRequestMessageFromViewerRequest(
        viewerRequestBuilder).build();

    transport.executeRequestAsync(requestMessage, new Callback<Response>() {
      public void onDone(Response result) {
      }

      public void onError(Throwable t) {
        unexpectedErrorLogger.log(TreeLogger.WARN,
            "An error occurred while attempting to add a log entry.", t);
      }
    });
  }

  /**
   * Add a new Module logger. This method should not be called multiple times
   * with the exact same arguments (as there should only be one logger
   * associated with that set of arguments).
   * 
   * @param remoteSocket name of remote socket endpoint in host:port format
   * @param url URL of top-level window
   * @param tabKey stable browser tab identifier, or the empty string if no such
   *          identifier is available
   * @param moduleName the name of the module loaded
   * @param sessionKey a unique session key
   * @param agentTag short-form user agent identifier, suitable for use in a
   *          label for this connection
   * @param agentIcon icon to use for the user agent (fits inside 24x24) or null
   *          if unavailable
   * @return the log handle for the newly-created Module logger
   */
  public int addModuleLog(String remoteSocket, String url, String tabKey,
      String moduleName, String sessionKey, String agentTag, byte[] agentIcon) {
    ViewerRequest.AddLog.ModuleLog.Builder moduleLogBuilder = ViewerRequest.AddLog.ModuleLog.newBuilder();
    moduleLogBuilder.setName(moduleName);
    moduleLogBuilder.setUserAgent(agentTag);

    if (url != null) {
      moduleLogBuilder.setUrl(url);
    }

    moduleLogBuilder.setRemoteHost(remoteSocket);
    moduleLogBuilder.setSessionKey(sessionKey);

    if (tabKey != null) {
      moduleLogBuilder.setTabKey(tabKey);
    }

    if (agentIcon != null) {
      moduleLogBuilder = moduleLogBuilder.setIcon(ByteString.copyFrom(agentIcon));
    }

    ViewerRequest.AddLog.Builder addLogBuilder = ViewerRequest.AddLog.newBuilder();
    addLogBuilder.setType(ViewerRequest.AddLog.LogType.MODULE);
    addLogBuilder.setModuleLog(moduleLogBuilder);

    return createLogger(addLogBuilder);
  }

  /**
   * Check the capabilities of the ViewerService. Ensures that the ViewerService
   * supports: adding a log, adding a log branch, adding a log entry, and
   * disconnecting a log.
   * 
   * TODO: Should we be checking the specific capability of the the
   * ViewerService to support logs of type MAIN, SERVER, and MODULE? Right now,
   * we assume that if they can support the addition of logs, they can handle
   * the addition of any types of logs that we throw at them.
   */
  public void checkCapabilities() {
    ViewerRequest.CapabilityExchange.Builder capabilityExchangeBuilder = ViewerRequest.CapabilityExchange.newBuilder();
    ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
    viewerRequestBuilder.setRequestType(ViewerRequest.RequestType.CAPABILITY_EXCHANGE);
    viewerRequestBuilder.setCapabilityExchange(capabilityExchangeBuilder);

    Request.Builder request = buildRequestMessageFromViewerRequest(viewerRequestBuilder);

    Future<Response> responseFuture = transport.executeRequestAsync(request.build());
    Response response = waitForResponseOrThrowUncheckedException(responseFuture);

    ViewerResponse.CapabilityExchange capabilityExchangeResponse = response.getViewerResponse().getCapabilityExchange();
    List<Capability> capabilityList = capabilityExchangeResponse.getCapabilitiesList();

    // Check for the add log ability
    checkCapability(capabilityList, RequestType.ADD_LOG);

    // Check for the add log branch ability
    checkCapability(capabilityList, RequestType.ADD_LOG_BRANCH);

    // Check for the add log branch ability
    checkCapability(capabilityList, RequestType.ADD_LOG_BRANCH);

    // Check for the disconnect log capability
    checkCapability(capabilityList, RequestType.DISCONNECT_LOG);
  }

  /**
   * Disconnect the log. Indicate to the log that the process which was logging
   * messages to it is now dead, and no more messages will be logged to it.
   * 
   * Note that the log handle should refer to a top-level log, not a branch log.
   * 
   * @param logHandle the handle of the top-level log to disconnect
   */
  public void disconnectLog(int logHandle) {
    ViewerRequest.DisconnectLog.Builder disconnectLogbuilder = ViewerRequest.DisconnectLog.newBuilder();
    disconnectLogbuilder.setLogHandle(logHandle);

    ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
    viewerRequestBuilder.setRequestType(RequestType.DISCONNECT_LOG);
    viewerRequestBuilder.setDisconnectLog(disconnectLogbuilder);

    Request.Builder request = buildRequestMessageFromViewerRequest(viewerRequestBuilder);
    Future<Response> responseFuture = transport.executeRequestAsync(request.build());
    waitForResponseOrThrowUncheckedException(responseFuture);
  }

  public void initialize(String clientId, List<String> startupURLs) {
    ViewerRequest.Initialize.Builder initializationBuilder = ViewerRequest.Initialize.newBuilder();
    initializationBuilder.setClientId(clientId);
    initializationBuilder.addAllStartupURLs(startupURLs);

    ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
    viewerRequestBuilder.setRequestType(ViewerRequest.RequestType.INITIALIZE);
    viewerRequestBuilder.setInitialize(initializationBuilder);

    Request.Builder request = buildRequestMessageFromViewerRequest(viewerRequestBuilder);

    Future<Response> responseFuture = transport.executeRequestAsync(request.build());
    waitForResponseOrThrowUncheckedException(responseFuture);
  }

  private Request.Builder buildRequestMessageFromViewerRequest(
      ViewerRequest.Builder viewerRequestBuilder) {
    return Request.newBuilder().setServiceType(Request.ServiceType.VIEWER).setViewerRequest(
        viewerRequestBuilder);
  }

  private void checkCapability(List<Capability> viewerCapabilityList,
      RequestType capabilityWeNeed) {
    for (Capability c : viewerCapabilityList) {
      if (c.getCapability() == capabilityWeNeed) {
        return;
      }
    }
    throw new RuntimeException("ViewerService does not support "
        + capabilityWeNeed.toString());
  }

  private int createLogger(ViewerRequest.AddLog.Builder addLogBuilder) {
    ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
    viewerRequestBuilder.setRequestType(ViewerRequest.RequestType.ADD_LOG);
    viewerRequestBuilder.setAddLog(addLogBuilder);

    Request.Builder request = buildRequestMessageFromViewerRequest(viewerRequestBuilder);

    Future<Response> responseFuture = transport.executeRequestAsync(request.build());
    return waitForResponseOrThrowUncheckedException(responseFuture).getViewerResponse().getAddLog().getLogHandle();
  }

  private LogData.Builder generateLogData(Type type, String msg,
      Throwable caught, HelpInfo helpInfo) {
    LogData.Builder logBuilder = LogData.newBuilder().setSummary(msg);
    logBuilder.setLevel(type.getLabel());

    if (caught != null) {
      String stackTraceAsString = AbstractTreeLogger.getStackTraceAsString(caught);
      if (stackTraceAsString != null) {
        logBuilder = logBuilder.setDetails(stackTraceAsString);
      }
    }

    if (helpInfo != null) {
      LogData.HelpInfo.Builder helpInfoBuilder = LogData.HelpInfo.newBuilder();

      if (helpInfo.getURL() != null) {
        helpInfoBuilder.setUrl(helpInfo.getURL().toExternalForm());
      }

      if (helpInfo.getAnchorText() != null) {
        helpInfoBuilder.setText(helpInfo.getAnchorText());
      }

      logBuilder.setHelpInfo(helpInfoBuilder);
    }

    if (type.needsAttention()) {
      // Set this field if attention is actually needed
      logBuilder.setNeedsAttention(true);
    }

    return logBuilder;
  }

  /**
   * Waits for response and throws a checked exception if the request failed.
   * 
   * Requests can fail if the other side does not understand the message -- for
   * example, if it is running an older version.
   * 
   * @throws RequestException if the request failed
   */
  private Response waitForResponse(Future<Response> future)
      throws RequestException {
    try {
      return future.get();
    } catch (ExecutionException e) {
      Throwable cause = e.getCause();
      if (cause instanceof RequestException) {
        throw (RequestException) cause;
      } else {
        throw new RuntimeException(e);
      }
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Waits for response and throws an unchecked exception if the request failed.
   */
  private Response waitForResponseOrThrowUncheckedException(
      Future<Response> future) {
    try {
      return waitForResponse(future);
    } catch (RequestException e) {
      throw new RuntimeException(e);
    }
  }
}
