// Copyright (C) 2009 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.sshd.commands;

import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;

import com.google.common.base.Objects;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.TaskInfoFactory;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.git.WorkQueue.ProjectTask;
import com.google.gerrit.server.git.WorkQueue.Task;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.util.IdGenerator;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gerrit.sshd.AdminHighPriorityCommand;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;

import org.apache.sshd.server.Environment;
import org.kohsuke.args4j.Option;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/** Display the current work queue. */
@AdminHighPriorityCommand
@CommandMetaData(name = "show-queue", description = "Display the background work queues",
  runsAt = MASTER_OR_SLAVE)
final class ShowQueue extends SshCommand {
  @Option(name = "--wide", aliases = {"-w"}, usage = "display without line width truncation")
  private boolean wide;

  @Inject
  private WorkQueue workQueue;

  @Inject
  private ProjectCache projectCache;

  @Inject
  private IdentifiedUser currentUser;

  private int columns = 80;
  private int taskNameWidth;

  @Override
  public void start(final Environment env) throws IOException {
    String s = env.getEnv().get(Environment.ENV_COLUMNS);
    if (s != null && !s.isEmpty()) {
      try {
        columns = Integer.parseInt(s);
      } catch (NumberFormatException err) {
        columns = 80;
      }
    }
    super.start(env);
  }

  @Override
  protected void run() {
    taskNameWidth = wide ? Integer.MAX_VALUE : columns - 8 - 12 - 12 - 4 - 4;
    final List<QueueTaskInfo> pending = getSortedTaskInfoList();

    stdout.print(String.format("%-8s %-12s %-12s %-4s %s\n", //
        "Task", "State", "StartTime", "", "Command"));
    stdout.print("----------------------------------------------"
        + "--------------------------------\n");

    int numberOfPendingTasks = 0;
    final long now = TimeUtil.nowMs();
    final boolean viewAll = currentUser.getCapabilities().canViewQueue();

    for (final QueueTaskInfo taskInfo : pending) {
      final long delay = taskInfo.delayMillis;
      final Task.State state = taskInfo.state;

      final String start;
      switch (state) {
        case DONE:
        case CANCELLED:
        case RUNNING:
        case READY:
          start = format(state);
          break;
        default:
          start = time(now, delay);
          break;
      }

      boolean regularUserCanSee = false;
      boolean hasCustomizedPrint = true;

      // If the user is not administrator, check if has rights to see
      // the Task
      Project.NameKey projectName = null;
      String remoteName = null;

      if (!viewAll) {
        projectName = taskInfo.getProjectNameKey();
        remoteName = taskInfo.getRemoteName();
        hasCustomizedPrint = taskInfo.hasCustomizedPrint();

        ProjectState e = null;
        if (projectName != null) {
          e = projectCache.get(projectName);
        }

        regularUserCanSee = e != null && e.controlFor(currentUser).isVisible();

        if (regularUserCanSee) {
          numberOfPendingTasks++;
        }
      }

      String startTime = startTime(taskInfo.getStartTime());

      // Shows information about tasks depending on the user rights
      if (viewAll || (!hasCustomizedPrint && regularUserCanSee)) {
        stdout.print(String.format("%8s %-12s %-12s %-4s %s\n", //
            id(taskInfo.getTaskId()), start, startTime, "",
            taskInfo.getTaskString(taskNameWidth)));
      } else if (regularUserCanSee) {
        if (projectName != null) {
          if (remoteName == null) {
            remoteName = projectName.get();
          } else {
            remoteName = remoteName + "/" + projectName.get();
          }
        }

        stdout.print(String.format("%8s %-12s %-4s %s\n",
            id(taskInfo.getTaskId()), start, startTime,
            Objects.firstNonNull(remoteName, "n/a")));
      }
    }
    stdout.print("----------------------------------------------"
        + "--------------------------------\n");

    if (viewAll) {
      numberOfPendingTasks = pending.size();
    }

    stdout.print("  " + numberOfPendingTasks + " tasks\n");
  }

  private List<QueueTaskInfo> getSortedTaskInfoList() {
    final List<QueueTaskInfo> taskInfos =
        workQueue.getTaskInfos(new TaskInfoFactory<QueueTaskInfo>() {
          @Override
          public QueueTaskInfo getTaskInfo(Task<?> task) {
            return new QueueTaskInfo(task);
          }
        });
    Collections.sort(taskInfos, new Comparator<QueueTaskInfo>() {
      @Override
      public int compare(QueueTaskInfo a, QueueTaskInfo b) {
        if (a.state != b.state) {
          return a.state.ordinal() - b.state.ordinal();
        }

        int cmp = Long.signum(a.delayMillis - b.delayMillis);
        if (cmp != 0) {
          return cmp;
        }

        return a.getTaskString(taskNameWidth)
            .compareTo(b.getTaskString(taskNameWidth));
      }
    });
    return taskInfos;
  }

  private static String id(final int id) {
    return IdGenerator.format(id);
  }

  private static String time(final long now, final long delay) {
    final Date when = new Date(now + delay);
    return format(when, delay);
  }

  private static String startTime(final Date when) {
    return format(when, TimeUtil.nowMs() - when.getTime());
  }

  private static String format(final Date when, final long timeFromNow) {
    if (timeFromNow < 24 * 60 * 60 * 1000L) {
      return new SimpleDateFormat("HH:mm:ss.SSS").format(when);
    }
    return new SimpleDateFormat("MMM-dd HH:mm").format(when);
  }

  private static String format(final Task.State state) {
    switch (state) {
      case DONE:
        return "....... done";
      case CANCELLED:
        return "..... killed";
      case RUNNING:
        return "";
      case READY:
        return "waiting ....";
      case SLEEPING:
        return "sleeping";
      default:
        return state.toString();
    }
  }

  private static class QueueTaskInfo {
    private final long delayMillis;
    private final Task.State state;
    private final Task<?> task;

    QueueTaskInfo(Task<?> task) {
      this.task = task;
      this.delayMillis = task.getDelay(TimeUnit.MILLISECONDS);
      this.state = task.getState();
    }

    String getRemoteName() {
      if (task instanceof ProjectTask) {
        return ((ProjectTask<?>) task).getRemoteName();
      }
      return null;
    }

    Project.NameKey getProjectNameKey() {
      if (task instanceof ProjectTask<?>) {
        return ((ProjectTask<?>) task).getProjectNameKey();
      }
      return null;
    }

    boolean hasCustomizedPrint() {
      if (task instanceof ProjectTask<?>) {
        return ((ProjectTask<?>) task).hasCustomizedPrint();
      }
      return false;
    }

    int getTaskId() {
      return task.getTaskId();
    }

    Date getStartTime() {
      return task.getStartTime();
    }

    String getTaskString(int maxLength) {
      String s = task.toString();
      return s.length() < maxLength ? s : s.substring(0, maxLength);
    }
  }
}
