package com.airlock.iam.application.webserver.infrastructure.health;

import java.lang.management.CompilationMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.time.Instant;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;

public class RuntimeCheck implements HealthCheck {
   private final RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
   private final CompilationMXBean compilationBean = ManagementFactory.getCompilationMXBean();
   private final MemoryUsage memoryUsageBean = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
   private final OperatingSystemMXBean operatingSystemBean = ManagementFactory.getOperatingSystemMXBean();

   public HealthCheckResponse call() {
      return HealthCheckResponse.named("runtime")
         .up()
         .withData("pid", this.runtimeBean.getPid())
         .withData("startTime", formatTimestamp(this.runtimeBean.getStartTime()))
         .withData("uptime", this.runtimeBean.getUptime())
         .withData("version", this.runtimeBean.getVmVersion())
         .withData("compilationTime", this.compilationBean.getTotalCompilationTime())
         .withData("memoryMax", this.memoryUsageBean.getMax())
         .withData("memoryCommitted", this.memoryUsageBean.getCommitted())
         .withData("memoryUsed", this.memoryUsageBean.getUsed())
         .withData("systemLoadAverage", Double.toString(this.operatingSystemBean.getSystemLoadAverage()))
         .build();
   }

   private static String formatTimestamp(long timestamp) {
      return Instant.ofEpochMilli(timestamp).toString();
   }
}
