/*
 * 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.dev.util.Callback;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.log.AbstractTreeLogger;

import java.util.List;

/**
 * A tree logger that creates log entries using a ViewerService.
 */
public final class ViewerServiceTreeLogger extends AbstractTreeLogger {

  private abstract class Pending {
    protected final Throwable caught;
    protected final HelpInfo helpInfo;
    protected final String msg;
    protected final TreeLogger.Type type;

    public Pending(Type type, String msg, Throwable caught, HelpInfo helpInfo) {
      this.caught = caught;
      this.msg = msg;
      this.type = type;
      this.helpInfo = helpInfo;
    }

    public abstract void send();
  }

  private class PendingBranch extends Pending {
    public final ViewerServiceTreeLogger branch;

    public PendingBranch(ViewerServiceTreeLogger branch, Type type, String msg,
        Throwable caught, HelpInfo helpInfo) {
      super(type, msg, caught, helpInfo);
      this.branch = branch;
    }

    @Override
    public void send() {
      sendBranch(branch, type, msg, caught, helpInfo);
    }
  }

  private class PendingLog extends Pending {
    protected final int indexOfLogEntry;

    public PendingLog(int indexOfLogEntry, Type type, String msg,
        Throwable caught, HelpInfo helpInfo) {
      super(type, msg, caught, helpInfo);
      this.indexOfLogEntry = indexOfLogEntry;
    }

    @Override
    public void send() {
      sendEntry(indexOfLogEntry, type, msg, caught, helpInfo);
    }
  }

  private volatile int logHandle = -1;

  private List<Pending> pending = Lists.create();

  private final ViewerServiceClient viewerServiceClient;

  /**
   * Creates a new instance with the given Viewer Service requestor.
   * 
   * @param viewerServiceClient An object that can be used to make requests to a
   *          viewer service server.
   */
  public ViewerServiceTreeLogger(ViewerServiceClient viewerServiceClient) {
    this.viewerServiceClient = viewerServiceClient;
  }

  /**
   * Creates a new logger for a branch. Note that the logger's handle has not
   * been set as yet; it will only be set once the branch is committed.
   */
  @Override
  protected AbstractTreeLogger doBranch() {
    return new ViewerServiceTreeLogger(viewerServiceClient);
  }

  @Override
  protected void doCommitBranch(AbstractTreeLogger childBeingCommitted,
      Type type, String msg, Throwable caught, HelpInfo helpInfo) {
    // Already synchronized via superclass.
    ViewerServiceTreeLogger child = (ViewerServiceTreeLogger) childBeingCommitted;
    if (isSent()) {
      // Immediately send the child branch.
      sendBranch(child, type, msg, caught, helpInfo);
    } else {
      // Queue the child branch until I'm committed.
      pending = Lists.add(pending, new PendingBranch(child, type, msg, caught,
          helpInfo));
    }
  }

  @Override
  protected void doLog(int indexOfLogEntry, Type type, String msg,
      Throwable caught, HelpInfo helpInfo) {
    // Already synchronized via superclass.
    if (isSent()) {
      // Immediately send the child log entry.
      sendEntry(indexOfLogEntry, type, msg, caught, helpInfo);
    } else {
      // Queue the log entry until I'm committed.
      pending = Lists.add(pending, new PendingLog(indexOfLogEntry, type, msg,
          caught, helpInfo));
    }
  }

  synchronized void initLogHandle(int newLogHandle) {
    assert !isSent();
    logHandle = newLogHandle;
    for (Pending item : pending) {
      item.send();
    }
    pending = null;
  }

  void sendBranch(final ViewerServiceTreeLogger branch, Type type, String msg,
      Throwable caught, HelpInfo helpInfo) {
    assert isSent();
    viewerServiceClient.addLogBranch(branch.getBranchedIndex(), type, msg,
        caught, helpInfo, logHandle, new Callback<Integer>() {
          public void onDone(Integer result) {
            branch.initLogHandle(result);
          }

          public void onError(Throwable t) {
            // TODO(rdayal): handle errors?
          }
        });
  }

  void sendEntry(int indexOfLogEntry, Type type, String msg, Throwable caught,
      HelpInfo helpInfo) {
    assert isSent();
    viewerServiceClient.addLogEntry(indexOfLogEntry, type, msg, caught,
        helpInfo, logHandle);
  }

  private boolean isSent() {
    return logHandle >= 0;
  }
}
