// Copyright (C) 2015 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.metrics.proc;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Version;
import com.google.gerrit.metrics.CallbackMetric0;
import com.google.gerrit.metrics.CallbackMetric1;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.server.logging.Metadata;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.TimeUnit;

public class ProcMetricModule extends MetricModule {
  @Override
  protected void configure(MetricMaker metrics) {
    buildLabel(metrics);
    procUptime(metrics);
    procCpuUsage(metrics);
    procCpuLoad(metrics);
    procJvmGc(metrics);
    procJvmMemory(metrics);
    procJvmThread(metrics);
  }

  private void buildLabel(MetricMaker metrics) {
    metrics.newConstantMetric(
        "build/label",
        Strings.nullToEmpty(Version.getVersion()),
        new Description("Version of Gerrit server software"));
  }

  private void procUptime(MetricMaker metrics) {
    metrics.newConstantMetric(
        "proc/birth_timestamp",
        Long.valueOf(TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis())),
        new Description("Time at which the process started").setUnit(Units.MICROSECONDS));

    metrics.newCallbackMetric(
        "proc/uptime",
        Long.class,
        new Description("Uptime of this process").setUnit(Units.MILLISECONDS),
        ManagementFactory.getRuntimeMXBean()::getUptime);
  }

  private void procCpuUsage(MetricMaker metrics) {
    OperatingSystemMXBeanInterface provider = OperatingSystemMXBeanFactory.create();

    if (provider == null) {
      return;
    }

    if (provider.getProcessCpuTime() != -1) {
      metrics.newCallbackMetric(
          "proc/cpu/usage",
          Double.class,
          new Description("CPU time used by the process").setCumulative().setUnit(Units.SECONDS),
          () -> provider.getProcessCpuTime() / 1e9);
    }

    if (provider.getOpenFileDescriptorCount() != -1) {
      metrics.newCallbackMetric(
          "proc/num_open_fds",
          Long.class,
          new Description("Number of open file descriptors").setGauge().setUnit("fds"),
          provider::getOpenFileDescriptorCount);
    }
    metrics.newCallbackMetric(
        "proc/cpu/num_cores",
        Integer.class,
        new Description("Number of processors available to the Java virtual machine").setGauge(),
        Runtime.getRuntime()::availableProcessors);
  }

  private void procCpuLoad(MetricMaker metrics) {
    OperatingSystemMXBean provider =
        ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
    if (provider.getSystemLoadAverage() != -1) {
      metrics.newCallbackMetric(
          "proc/cpu/system_load",
          Double.class,
          new Description("System load average for the last minute").setGauge(),
          provider::getSystemLoadAverage);
    }
  }

  private void procJvmMemory(MetricMaker metrics) {
    CallbackMetric0<Long> heapCommitted =
        metrics.newCallbackMetric(
            "proc/jvm/memory/heap_committed",
            Long.class,
            new Description("Amount of memory guaranteed for user objects.")
                .setGauge()
                .setUnit(Units.BYTES));

    CallbackMetric0<Long> heapUsed =
        metrics.newCallbackMetric(
            "proc/jvm/memory/heap_used",
            Long.class,
            new Description("Amount of memory holding user objects.")
                .setGauge()
                .setUnit(Units.BYTES));

    CallbackMetric0<Long> nonHeapCommitted =
        metrics.newCallbackMetric(
            "proc/jvm/memory/non_heap_committed",
            Long.class,
            new Description("Amount of memory guaranteed for classes, etc.")
                .setGauge()
                .setUnit(Units.BYTES));

    CallbackMetric0<Long> nonHeapUsed =
        metrics.newCallbackMetric(
            "proc/jvm/memory/non_heap_used",
            Long.class,
            new Description("Amount of memory holding classes, etc.")
                .setGauge()
                .setUnit(Units.BYTES));

    CallbackMetric0<Integer> objectPendingFinalizationCount =
        metrics.newCallbackMetric(
            "proc/jvm/memory/object_pending_finalization_count",
            Integer.class,
            new Description("Approximate number of objects needing finalization.")
                .setGauge()
                .setUnit("objects"));

    MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
    metrics.newTrigger(
        ImmutableSet.of(
            heapCommitted, heapUsed, nonHeapCommitted, nonHeapUsed, objectPendingFinalizationCount),
        () -> {
          try {
            MemoryUsage stats = memory.getHeapMemoryUsage();
            heapCommitted.set(stats.getCommitted());
            heapUsed.set(stats.getUsed());
          } catch (IllegalArgumentException e) {
            // MXBean may throw due to a bug in Java 7; ignore.
          }

          MemoryUsage stats = memory.getNonHeapMemoryUsage();
          nonHeapCommitted.set(stats.getCommitted());
          nonHeapUsed.set(stats.getUsed());

          objectPendingFinalizationCount.set(memory.getObjectPendingFinalizationCount());
        });
  }

  private void procJvmGc(MetricMaker metrics) {
    Field<String> gcNameField =
        Field.ofString("gc_name", Metadata.Builder::garbageCollectorName)
            .description("The name of the garbage collector")
            .build();

    CallbackMetric1<String, Long> gcCount =
        metrics.newCallbackMetric(
            "proc/jvm/gc/count",
            Long.class,
            new Description("Number of GCs").setCumulative(),
            gcNameField);

    CallbackMetric1<String, Long> gcTime =
        metrics.newCallbackMetric(
            "proc/jvm/gc/time",
            Long.class,
            new Description("Approximate accumulated GC elapsed time")
                .setCumulative()
                .setUnit(Units.MILLISECONDS),
            gcNameField);

    metrics.newTrigger(
        gcCount,
        gcTime,
        () -> {
          for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
            long count = gc.getCollectionCount();
            if (count != -1) {
              gcCount.set(gc.getName(), count);
            }
            long time = gc.getCollectionTime();
            if (time != -1) {
              gcTime.set(gc.getName(), time);
            }
          }
        });
  }

  private void procJvmThread(MetricMaker metrics) {
    ThreadMXBean thread = ManagementFactory.getThreadMXBean();
    metrics.newCallbackMetric(
        "proc/jvm/thread/num_live",
        Integer.class,
        new Description("Current live thread count").setGauge().setUnit("threads"),
        thread::getThreadCount);
    metrics.newCallbackMetric(
        "proc/jvm/thread/num_daemon_live",
        Integer.class,
        new Description("Current live daemon threads count").setGauge().setUnit("threads"),
        thread::getDaemonThreadCount);
    metrics.newCallbackMetric(
        "proc/jvm/thread/num_peak_live",
        Integer.class,
        new Description(
                "Peak live thread count since the Java virtual machine started or peak was reset")
            .setGauge()
            .setUnit("threads"),
        thread::getPeakThreadCount);
    metrics.newCallbackMetric(
        "proc/jvm/thread/num_total_started",
        Long.class,
        new Description(
                "Total number of threads created and also started since the Java virtual machine started")
            .setGauge()
            .setUnit("threads"),
        thread::getTotalStartedThreadCount);
    if (thread.isSynchronizerUsageSupported()) {
      metrics.newCallbackMetric(
          "proc/jvm/thread/num_deadlocked_threads",
          Integer.class,
          new Description(
                  "number of threads that are deadlocked waiting for object monitors or ownable synchronizers")
              .setGauge()
              .setUnit("threads"),
          () -> {
            long[] deadlocked = thread.findDeadlockedThreads();
            if (deadlocked == null) {
              return 0;
            }
            return deadlocked.length;
          });
    } else {
      metrics.newCallbackMetric(
          "proc/jvm/thread/num_deadlocked_threads",
          Integer.class,
          new Description(
                  "number of threads that are deadlocked waiting to acquire object monitors")
              .setGauge()
              .setUnit("threads"),
          () -> {
            long[] deadlocked = thread.findMonitorDeadlockedThreads();
            if (deadlocked == null) {
              return 0;
            }
            return deadlocked.length;
          });
    }
  }
}
