// 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.common.data.GlobalCapability.MAINTAIN_SERVER;
import static com.google.gerrit.common.data.GlobalCapability.VIEW_CACHES;
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;

import com.google.common.base.Strings;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.Version;
import com.google.gerrit.extensions.annotations.RequiresAnyCapability;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.ConfigResource;
import com.google.gerrit.server.config.GetSummary;
import com.google.gerrit.server.config.GetSummary.JvmSummaryInfo;
import com.google.gerrit.server.config.GetSummary.MemSummaryInfo;
import com.google.gerrit.server.config.GetSummary.SummaryInfo;
import com.google.gerrit.server.config.GetSummary.TaskSummaryInfo;
import com.google.gerrit.server.config.GetSummary.ThreadSummaryInfo;
import com.google.gerrit.server.config.ListCaches;
import com.google.gerrit.server.config.ListCaches.CacheInfo;
import com.google.gerrit.server.config.ListCaches.CacheType;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.SshDaemon;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.apache.sshd.common.io.IoAcceptor;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.mina.MinaSession;
import org.apache.sshd.server.Environment;
import org.kohsuke.args4j.Option;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

/** Show the current cache states. */
@RequiresAnyCapability({VIEW_CACHES, MAINTAIN_SERVER})
@CommandMetaData(name = "show-caches", description = "Display current cache statistics",
  runsAt = MASTER_OR_SLAVE)
final class ShowCaches extends SshCommand {
  private static volatile long serverStarted;

  static class StartupListener implements LifecycleListener {
    @Override
    public void start() {
      serverStarted = TimeUtil.nowMs();
    }

    @Override
    public void stop() {
    }
  }

  @Option(name = "--gc", usage = "perform Java GC before printing memory stats")
  private boolean gc;

  @Option(name = "--show-jvm", usage = "show details about the JVM")
  private boolean showJVM;

  @Option(name = "--show-threads", usage = "show detailed thread counts")
  private boolean showThreads;

  @Inject
  private SshDaemon daemon;

  @Inject
  private Provider<ListCaches> listCaches;

  @Inject
  private Provider<GetSummary> getSummary;

  @Inject
  private Provider<CurrentUser> self;

  @Option(name = "--width", aliases = {"-w"}, metaVar = "COLS", usage = "width of output table")
  private int columns = 80;
  private int nw;

  @Override
  public void start(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() throws UnloggedFailure {
    nw = columns - 50;
    Date now = new Date();
    stdout.format(
        "%-25s %-20s      now  %16s\n",
        "Gerrit Code Review",
        Version.getVersion() != null ? Version.getVersion() : "",
        new SimpleDateFormat("HH:mm:ss   zzz").format(now));
    stdout.format(
        "%-25s %-20s   uptime %16s\n",
        "", "",
        uptime(now.getTime() - serverStarted));
    stdout.print('\n');

    stdout.print(String.format(//
        "%1s %-"+nw+"s|%-21s|  %-5s |%-9s|\n" //
        , "" //
        , "Name" //
        , "Entries" //
        , "AvgGet" //
        , "Hit Ratio" //
    ));
    stdout.print(String.format(//
        "%1s %-"+nw+"s|%6s %6s %7s|  %-5s  |%-4s %-4s|\n" //
        , "" //
        , "" //
        , "Mem" //
        , "Disk" //
        , "Space" //
        , "" //
        , "Mem" //
        , "Disk" //
    ));
    stdout.print("--");
    for (int i = 0; i < nw; i++) {
      stdout.print('-');
    }
    stdout.print("+---------------------+---------+---------+\n");

    Collection<CacheInfo> caches = getCaches();
    printMemoryCoreCaches(caches);
    printMemoryPluginCaches(caches);
    printDiskCaches(caches);
    stdout.print('\n');

    if (self.get().getCapabilities().canMaintainServer()) {
      sshSummary();

      SummaryInfo summary =
          getSummary.get().setGc(gc).setJvm(showJVM).apply(new ConfigResource());
      taskSummary(summary.taskSummary);
      memSummary(summary.memSummary);
      threadSummary(summary.threadSummary);

      if (showJVM && summary.jvmSummary != null) {
        jvmSummary(summary.jvmSummary);
      }
    }

    stdout.flush();
  }

  private Collection<CacheInfo> getCaches() {
    @SuppressWarnings("unchecked")
    Map<String, CacheInfo> caches =
        (Map<String, CacheInfo>) listCaches.get().apply(new ConfigResource());
    for (Map.Entry<String, CacheInfo> entry : caches.entrySet()) {
      CacheInfo cache = entry.getValue();
      cache.name = entry.getKey();
    }
    return caches.values();
  }

  private void printMemoryCoreCaches(Collection<CacheInfo> caches) {
    for (CacheInfo cache : caches) {
      if (!cache.name.contains("-") && CacheType.MEM.equals(cache.type)) {
        printCache(cache);
      }
    }
  }

  private void printMemoryPluginCaches(Collection<CacheInfo> caches) {
    for (CacheInfo cache : caches) {
      if (cache.name.contains("-") && CacheType.MEM.equals(cache.type)) {
        printCache(cache);
      }
    }
  }

  private void printDiskCaches(Collection<CacheInfo> caches) {
    for (CacheInfo cache : caches) {
      if (CacheType.DISK.equals(cache.type)) {
        printCache(cache);
      }
    }
  }

  private void printCache(CacheInfo cache) {
    stdout.print(String.format(
        "%1s %-"+nw+"s|%6s %6s %7s| %7s |%4s %4s|\n",
        CacheType.DISK.equals(cache.type) ? "D" : "",
        cache.name,
        nullToEmpty(cache.entries.mem),
        nullToEmpty(cache.entries.disk),
        Strings.nullToEmpty(cache.entries.space),
        Strings.nullToEmpty(cache.averageGet),
        formatAsPercent(cache.hitRatio.mem),
        formatAsPercent(cache.hitRatio.disk)
      ));
  }

  private static String nullToEmpty(Long l) {
    return l != null ? String.valueOf(l) : "";
  }

  private static String formatAsPercent(Integer i) {
    return i != null ? String.valueOf(i) + "%" : "";
  }

  private void memSummary(MemSummaryInfo memSummary) {
    stdout.format("Mem: %s total = %s used + %s free + %s buffers\n",
        memSummary.total,
        memSummary.used,
        memSummary.free,
        memSummary.buffers);
    stdout.format("     %s max\n", memSummary.max);
    stdout.format("    %8d open files\n",
        nullToZero(memSummary.openFiles));
    stdout.print('\n');
  }

  private void threadSummary(ThreadSummaryInfo threadSummary) {
    stdout.format("Threads: %d CPUs available, %d threads\n",
        threadSummary.cpus, threadSummary.threads);

    if (showThreads) {
      stdout.print(String.format("  %22s", ""));
      for (Thread.State s : Thread.State.values()) {
        stdout.print(String.format(" %14s", s.name()));
      }
      stdout.print('\n');
      for (Entry<String, Map<Thread.State, Integer>> e :
          threadSummary.counts.entrySet()) {
        stdout.print(String.format("  %-22s", e.getKey()));
        for (Thread.State s : Thread.State.values()) {
          stdout.print(String.format(" %14d", nullToZero(e.getValue().get(s))));
        }
        stdout.print('\n');
      }
    }
    stdout.print('\n');
  }

  private void taskSummary(TaskSummaryInfo taskSummary) {
    stdout.format(
        "Tasks: %4d  total = %4d running +   %4d ready + %4d sleeping\n",
        nullToZero(taskSummary.total),
        nullToZero(taskSummary.running),
        nullToZero(taskSummary.ready),
        nullToZero(taskSummary.sleeping));
  }

  private static int nullToZero(Integer i) {
    return i != null ? i : 0;
  }

  private void sshSummary() {
    IoAcceptor acceptor = daemon.getIoAcceptor();
    if (acceptor == null) {
      return;
    }

    long now = TimeUtil.nowMs();
    Collection<IoSession> list = acceptor.getManagedSessions().values();
    long oldest = now;

    for (IoSession s : list) {
      if (s instanceof MinaSession) {
        MinaSession minaSession = (MinaSession)s;
        oldest = Math.min(oldest, minaSession.getSession().getCreationTime());
      }
    }

    stdout.format(
        "SSH:   %4d  users, oldest session started %s ago\n",
        list.size(),
        uptime(now - oldest));
  }

  private void jvmSummary(JvmSummaryInfo jvmSummary) {
    stdout.format("JVM: %s %s %s\n",
        jvmSummary.vmVendor,
        jvmSummary.vmName,
        jvmSummary.vmVersion);
    stdout.format("  on %s %s %s\n",
        jvmSummary.osName,
        jvmSummary.osVersion,
        jvmSummary.osArch);
    stdout.format("  running as %s on %s\n",
        jvmSummary.user,
        Strings.nullToEmpty(jvmSummary.host));
    stdout.format("  cwd  %s\n", jvmSummary.currentWorkingDirectory);
    stdout.format("  site %s\n", jvmSummary.site);
  }

  private String uptime(long uptimeMillis) {
    if (uptimeMillis < 1000) {
      return String.format("%3d ms", uptimeMillis);
    }

    long uptime = uptimeMillis / 1000L;

    long min = uptime / 60;
    if (min < 60) {
      return String.format("%2d min %2d sec", min, uptime - min * 60);
    }

    long hr = uptime / 3600;
    if (hr < 24) {
      min = (uptime - hr * 3600) / 60;
      return String.format("%2d hrs %2d min", hr, min);
    }

    long days = uptime / (24 * 3600);
    hr = (uptime - (days * 24 * 3600)) / 3600;
    return String.format("%4d days %2d hrs", days, hr);
  }
}
