// 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 com.google.gerrit.sshd.AdminCommand;

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

import org.apache.sshd.server.Environment;
import org.eclipse.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(final Environment env) {
    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));
  }
}
