// Copyright (C) 2012 The Android Open Source Project
//
// 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.gerrit.server.git;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.OutputStream;

import java.util.concurrent.CancellationException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.List;

/**
 * Progress reporting interface that multiplexes multiple sub-tasks.
 * <p>
 * Output is of the format:
 * <pre>
 *   Task: subA: 1, subB: 75% (3/4) (-)\r
 *   Task: subA: 2, subB: 75% (3/4), subC: 1 (\)\r
 *   Task: subA: 2, subB: 100% (4/4), subC: 1 (|)\r
 *   Task: subA: 4, subB: 100% (4/4), subC: 4, done    \n
 * </pre>
 * <p>
 * Callers should try to keep task and sub-task descriptions short, since the
 * output should fit on one terminal line. (Note that git clients do not accept
 * terminal control characters, so true multi-line progress messages would be
 * impossible.)
 */
public class MultiProgressMonitor {
  private static final Logger log =
      LoggerFactory.getLogger(MultiProgressMonitor.class);

  /** Constant indicating the total work units cannot be predicted. */
  public static final int UNKNOWN = 0;

  private static final char[] SPINNER_STATES = new char[]{'-', '\\', '|', '/'};
  private static final char NO_SPINNER = ' ';

  /** Handle for a sub-task. */
  public class Task implements ProgressMonitor {
    private final String name;
    private final int total;
    private volatile int count;
    private int lastPercent;

    Task(final String subTaskName, final int totalWork) {
      this.name = subTaskName;
      this.total = totalWork;
    }

    /**
     * Indicate that work has been completed on this sub-task.
     * <p>
     * Must be called from the worker thread.
     *
     * @param completed number of work units completed.
     */
    @Override
    public void update(final int completed) {
      count += completed;
      if (total != UNKNOWN) {
        int percent = count * 100 / total;
        if (percent > lastPercent) {
          lastPercent = percent;
          wakeUp();
        }
      }
    }

    /**
     * Indicate that this sub-task is finished.
     * <p>
     * Must be called from the worker thread.
     */
    public void end() {
      if (total == UNKNOWN && count > 0) {
        wakeUp();
      }
    }

    @Override
    public void start(int totalTasks) {
    }

    @Override
    public void beginTask(String title, int totalWork) {
    }

    @Override
    public void endTask() {
    }

    @Override
    public boolean isCancelled() {
      return false;
    }
  }

  private final OutputStream out;
  private final String taskName;
  private final List<Task> tasks = new CopyOnWriteArrayList<Task>();
  private int spinnerIndex;
  private char spinnerState = NO_SPINNER;
  private boolean done;
  private boolean write = true;

  private final long maxIntervalNanos;

  /**
   * Create a new progress monitor for multiple sub-tasks.
   *
   * @param out stream for writing progress messages.
   * @param taskName name of the overall task.
   */
  public MultiProgressMonitor(final OutputStream out, final String taskName) {
    this(out, taskName, 500, TimeUnit.MILLISECONDS);
  }

  /**
   * Create a new progress monitor for multiple sub-tasks.
   *
   * @param out stream for writing progress messages.
   * @param taskName name of the overall task.
   * @param maxIntervalTime maximum interval between progress messages.
   * @param maxIntervalUnit time unit for progress interval.
   */
  public MultiProgressMonitor(final OutputStream out, final String taskName,
      long maxIntervalTime, TimeUnit maxIntervalUnit) {
    this.out = out;
    this.taskName = taskName;
    maxIntervalNanos = NANOSECONDS.convert(maxIntervalTime, maxIntervalUnit);
  }

  /**
   * Wait for a task managed by a {@link Future}, with no timeout.
   *
   * @see #waitFor(Future, long, TimeUnit)
   */
  public void waitFor(final Future<?> workerFuture) throws ExecutionException {
    waitFor(workerFuture, 0, null);
  }

  /**
   * Wait for a task managed by a {@link Future}.
   * <p>
   * Must be called from the main thread, <em>not</em> the worker thread. Once
   * the worker thread calls {@link #end()}, the future has an additional
   * <code>maxInterval</code> to finish before it is forcefully cancelled and
   * {@link ExecutionException} is thrown.
   *
   * @param workerFuture a future that returns when the worker thread is
   *     finished.
   * @param timeoutTime overall timeout for the task; the future is forcefully
   *     cancelled if the task exceeds the timeout. Non-positive values indicate
   *     no timeout.
   * @param timeoutUnit unit for overall task timeout.
   * @throws ExecutionException if this thread or the worker thread was
   *     interrupted, the worker was cancelled, or the worker timed out.
   */
  public void waitFor(final Future<?> workerFuture, final long timeoutTime,
      final TimeUnit timeoutUnit) throws ExecutionException {
    long overallStart = System.nanoTime();
    long deadline;
    String detailMessage = "";
    if (timeoutTime > 0) {
      deadline = overallStart + NANOSECONDS.convert(timeoutTime, timeoutUnit);
    } else {
      deadline = 0;
    }

    synchronized (this) {
      long left = maxIntervalNanos;
      while (!done) {
        long start = System.nanoTime();
        try {
          NANOSECONDS.timedWait(this, left);
        } catch (InterruptedException e) {
          throw new ExecutionException(e);
        }

        // Send an update on every wakeup (manual or spurious), but only move
        // the spinner every maxInterval.
        long now = System.nanoTime();

        if (deadline > 0 && now > deadline) {
          workerFuture.cancel(true);
          if (workerFuture.isCancelled()) {
            detailMessage = String.format(
                    "(timeout %sms, cancelled)",
                    TimeUnit.MILLISECONDS.convert(now - deadline, NANOSECONDS));
            log.warn(String.format(
                    "MultiProgressMonitor worker killed after %sms" + detailMessage, //
                    TimeUnit.MILLISECONDS.convert(now - overallStart, NANOSECONDS)));
          }
          break;
        }

        left -= now - start;
        if (left <= 0) {
          moveSpinner();
          left = maxIntervalNanos;
        }
        sendUpdate();
        if (!done && workerFuture.isDone()) {
          // The worker may not have called end() explicitly, which is likely a
          // programming error.
          log.warn("MultiProgressMonitor worker did not call end()"
              + " before returning");
          end();
        }
      }
      sendDone();
    }

    // The loop exits as soon as the worker calls end(), but we give it another
    // maxInterval to finish up and return.
    try {
      workerFuture.get(maxIntervalNanos, NANOSECONDS);
    } catch (InterruptedException e) {
      throw new ExecutionException(e);
    } catch (CancellationException e) {
      throw new ExecutionException(detailMessage, e);
    } catch (TimeoutException e) {
      workerFuture.cancel(true);
      throw new ExecutionException(e);
    }
  }

  private synchronized void wakeUp() {
    notifyAll();
  }

  /**
   * Begin a sub-task.
   *
   * @param subTask sub-task name.
   * @param subTaskWork total work units in sub-task, or {@link #UNKNOWN}.
   * @return sub-task handle.
   */
  public Task beginSubTask(final String subTask, final int subTaskWork) {
    Task task = new Task(subTask, subTaskWork);
    tasks.add(task);
    return task;
  }

  /**
   * End the overall task.
   * <p>
   * Must be called from the worker thread.
   */
  public synchronized void end() {
    done = true;
    wakeUp();
  }

  private void sendDone() {
    spinnerState = NO_SPINNER;
    StringBuilder s = format();
    boolean any = false;
    for (Task t : tasks) {
      if (t.count != 0) {
        any = true;
        break;
      }
    }
    if (any) {
      s.append(",");
    }
    s.append(" done    \n");
    send(s);
  }

  private void moveSpinner() {
    spinnerIndex = (spinnerIndex + 1) % SPINNER_STATES.length;
    spinnerState = SPINNER_STATES[spinnerIndex];
  }

  private void sendUpdate() {
    send(format());
  }

  private StringBuilder format() {
    StringBuilder s = new StringBuilder().append("\r").append(taskName)
        .append(':');

    if (!tasks.isEmpty()) {
      boolean first = true;
      for (Task t : tasks) {
        int count = t.count;
        if (count == 0) {
          continue;
        }

        if (!first) {
          s.append(',');
        } else {
          first = false;
        }

        s.append(' ').append(t.name).append(": ");
        if (t.total == UNKNOWN) {
          s.append(count);
        } else {
          s.append(String.format("%d%% (%d/%d)",
              count * 100 / t.total,
              count, t.total));
        }
      }
    }

    if (spinnerState != NO_SPINNER) {
      // Don't output a spinner until the alarm fires for the first time.
      s.append(" (").append(spinnerState).append(')');
    }
    return s;
  }

  private void send(StringBuilder s) {
    if (write) {
      try {
        out.write(Constants.encode(s.toString()));
        out.flush();
      } catch (IOException e) {
        write = false;
      }
    }
  }
}
