// 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.server.ssh.commands;

import com.google.gerrit.server.ssh.AdminCommand;

import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Statistics;
import net.sf.ehcache.config.CacheConfiguration;

import org.spearce.jgit.lib.WindowCacheStatAccessor;

import java.io.PrintWriter;

/** Show the current cache states. */
@AdminCommand
final class AdminShowCaches extends CacheCommand {
  private PrintWriter p;

  @Override
  public void start() {
    startThread(new CommandRunnable() {
      @Override
      public void run() throws Exception {
        parseCommandLine();
        display();
      }
    });
  }

  private void display() {
    p = toPrintWriter(out);

    p.print(String.format(//
        "%1s %-18s %-4s|%-20s|  %-5s  |%-14s|\n" //
        , "" //
        , "Name" //
        , "Max" //
        , "Object Count" //
        , "AvgGet" //
        , "Hit Ratio" //
    ));
    p.print(String.format(//
        "%1s %-18s %-4s|%6s %6s %6s|  %-5s   |%-4s %-4s %-4s|\n" //
        , "" //
        , "" //
        , "Age" //
        , "Disk" //
        , "Mem" //
        , "Cnt" //
        , "" //
        , "Disk" //
        , "Mem" //
        , "Agg" //
    ));
    p.println("------------------"
        + "-------+--------------------+----------+--------------+");
    for (final Ehcache cache : getAllCaches()) {
      final CacheConfiguration cfg = cache.getCacheConfiguration();
      final boolean useDisk = cfg.isDiskPersistent() || cfg.isOverflowToDisk();
      final Statistics stat = cache.getStatistics();
      final long total = stat.getCacheHits() + stat.getCacheMisses();

      if (useDisk) {
        p.print(String.format(//
            "D %-18s %-4s|%6s %6s %6s| %7s  |%4s %4s %4s|\n" //
            , cache.getName() //
            , interval(cfg.getTimeToLiveSeconds()) //
            , count(stat.getDiskStoreObjectCount()) //
            , count(stat.getMemoryStoreObjectCount()) //
            , count(stat.getObjectCount()) //
            , duration(stat.getAverageGetTime()) //
            , percent(stat.getOnDiskHits(), total) //
            , percent(stat.getInMemoryHits(), total) //
            , percent(stat.getCacheHits(), total) //
            ));
      } else {
        p.print(String.format(//
            "  %-18s %-4s|%6s %6s %6s| %7s  |%4s %4s %4s|\n" //
            , cache.getName() //
            , interval(cfg.getTimeToLiveSeconds()) //
            , "", "" //
            , count(stat.getObjectCount()) //
            , duration(stat.getAverageGetTime()) //
            , "", "" //
            , percent(stat.getCacheHits(), total) //
            ));
      }
    }
    p.println();

    final Runtime r = Runtime.getRuntime();
    final long mMax = r.maxMemory();
    final long mFree = r.freeMemory();
    final long mTotal = r.totalMemory();
    final long mInuse = mTotal - mFree;
    final long jgitBytes = WindowCacheStatAccessor.getOpenBytes();

    p.println("JGit Buffer Cache:");
    fItemCount("open files", WindowCacheStatAccessor.getOpenFiles());
    fByteCount("loaded", jgitBytes);
    fPercent("mem%", jgitBytes, mTotal);
    p.println();

    p.println("JVM Heap:");
    fByteCount("max", mMax);
    fByteCount("inuse", mInuse);
    fPercent("mem%", mInuse, mTotal);
    p.println();

    p.flush();
  }

  private void fItemCount(final String name, final long value) {
    p.println(String.format("  %1$-12s: %2$15d", name, value));
  }

  private void fByteCount(final String name, double value) {
    String suffix = "bytes";
    if (value > 1024) {
      value /= 1024;
      suffix = "kb";
    }
    if (value > 1024) {
      value /= 1024;
      suffix = "mb";
    }
    if (value > 1024) {
      value /= 1024;
      suffix = "gb";
    }
    p.println(String.format("  %1$-12s: %2$6.2f %3$s", name, value, suffix));
  }

  private String count(long cnt) {
    if (cnt == 0) {
      return "";
    }
    return String.format("%6d", cnt);
  }

  private String duration(double ms) {
    if (Math.abs(ms) <= 0.05) {
      return "";
    }
    String suffix = "ms";
    if (ms >= 1000) {
      ms /= 1000;
      suffix = "s ";
    }
    return String.format("%4.1f%s", ms, suffix);
  }

  private String interval(double ttl) {
    if (ttl == 0) {
      return "inf";
    }

    String suffix = "s";
    if (ttl >= 60) {
      ttl /= 60;
      suffix = "m";

      if (ttl >= 60) {
        ttl /= 60;
        suffix = "h";
      }

      if (ttl >= 24) {
        ttl /= 24;
        suffix = "d";

        if (ttl >= 365) {
          ttl /= 365;
          suffix = "y";
        }
      }
    }

    return Integer.toString((int) ttl) + suffix;
  }

  private String percent(final long value, final long total) {
    if (total <= 0) {
      return "";
    }
    final long pcent = (100 * value) / total;
    return String.format("%3d%%", (int) pcent);
  }

  private void fPercent(final String name, final long value, final long total) {
    final long pcent = 0 < total ? (100 * value) / total : 0;
    p.println(String.format("  %1$-12s: %2$3d%%", name, (int) pcent));
  }
}
