/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.geronimo.microprofile.metrics.common;

import java.lang.management.ClassLoadingMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.List;
import java.util.function.LongSupplier;

import javax.json.bind.annotation.JsonbTransient;

import org.eclipse.microprofile.metrics.Counter;
import org.eclipse.microprofile.metrics.Gauge;
import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricType;
import org.eclipse.microprofile.metrics.MetricUnits;
import org.eclipse.microprofile.metrics.Tag;

// isnt it super weird to hardcode that instead of defining a JMX integration?
// also the gauge/counter choice is quite surprising sometimes
public class BaseMetrics {
    private final MetricRegistry registry;

    public BaseMetrics(final MetricRegistry registry) {
        this.registry = registry;
    }

    public void register() {
        final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        registry.register(Metadata.builder()
                .withName("jvm.uptime")
                .withDisplayName("JVM Uptime")
                .withDescription("Displays the start time of the Java virtual machine in milliseconds." +
                        "This attribute displays the approximate time when the Java virtual machine started.")
                .withType(MetricType.GAUGE)
                .withUnit(MetricUnits.MILLISECONDS)
                .build(), gauge(runtimeMXBean::getUptime));

        final OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        registry.register(Metadata.builder()
                .withName("cpu.availableProcessors")
                .withDisplayName("Available Processors")
                .withDescription("Displays the number of processors available to the Java virtual machine. " +
                        "This value may change during a particular invocation of the virtual machine.")
                .withType(MetricType.GAUGE).withUnit(MetricUnits.NONE).build(), gauge(operatingSystemMXBean::getAvailableProcessors));

        final ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
        registry.register(Metadata.builder()
                .withName("classloader.unloadedClasses.count")
                .withDisplayName("Current Loaded Class Count")
                .withDescription("Displays the number of classes that are currently loaded in the Java virtual machine.")
                .withType(MetricType.GAUGE)
                .withUnit(MetricUnits.NONE)
                .build(),
                gauge(classLoadingMXBean::getUnloadedClassCount));
        registry.register(Metadata.builder()
                .withName("classloader.unloadedClasses.total")
                .withDisplayName("Current Loaded Class Total")
                .withDescription("Displays the number of classes that are currently loaded in the Java virtual machine.")
                .withType(MetricType.COUNTER)
                .withUnit(MetricUnits.NONE)
                .build(),
                counter(classLoadingMXBean::getUnloadedClassCount));
        registry.register(Metadata.builder()
                .withName("classloader.loadedClasses.count")
                .withDisplayName("Total Loaded Class Count")
                .withDescription("Displays the total number of classes that have been loaded since the Java virtual machine has started execution.")
                .withType(MetricType.GAUGE)
                .withUnit(MetricUnits.NONE)
                .build(),
                gauge(classLoadingMXBean::getTotalLoadedClassCount));
        registry.register(Metadata.builder()
                .withName("classloader.loadedClasses.total")
                .withDisplayName("Total Loaded Class Count")
                .withDescription("Displays the total number of classes that have been loaded since the Java virtual machine has started execution.")
                .withType(MetricType.COUNTER)
                .withUnit(MetricUnits.NONE)
                .build(),
                counter(classLoadingMXBean::getTotalLoadedClassCount));

        final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        registry.register(Metadata.builder()
                .withName("thread.count")
                .withDisplayName("Thread Count")
                .withDescription("Displays the current number of live threads including both daemon and non-daemon threads")
                .withType(MetricType.GAUGE)
                .withUnit(MetricUnits.NONE)
                .build(),
                gauge(threadMXBean::getThreadCount));
        registry.register(Metadata.builder()
                .withName("thread.daemon.count")
                .withDisplayName("Daemon Thread Count")
                .withDescription("Displays the current number of live daemon threads.")
                .withType(MetricType.GAUGE)
                .withUnit(MetricUnits.NONE)
                .build(),
                gauge(threadMXBean::getDaemonThreadCount));
        registry.register(Metadata.builder()
                .withName("thread.max.count")
                .withDisplayName("Peak Thread Count")
                .withDescription("Displays the peak live thread count since the Java virtual machine started or peak was reset." +
                        "This includes daemon and non-daemon threads.")
                .withType(MetricType.GAUGE)
                .withUnit(MetricUnits.NONE)
                .build(),
                gauge(threadMXBean::getPeakThreadCount));

        final MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        registry.register(Metadata.builder()
                .withName("memory.usedHeap")
                .withDisplayName("Used Heap Memory")
                .withDescription("Displays the amount of used heap memory in bytes.")
                .withType(MetricType.GAUGE).withUnit(MetricUnits.BYTES).build(), gauge(memoryMXBean.getHeapMemoryUsage()::getUsed));
        registry.register(Metadata.builder()
                .withName("memory.committedHeap")
                .withDisplayName("Committed Heap Memory")
                .withDescription("Displays the amount of memory in bytes that is committed for the Java virtual machine to use. " +
                        "This amount of memory is guaranteed for the Java virtual machine to use.")
                .withType(MetricType.GAUGE).withUnit(MetricUnits.BYTES).build(), gauge(memoryMXBean.getHeapMemoryUsage()::getCommitted));
        registry.register(Metadata.builder()
                .withName("memory.maxHeap")
                .withDisplayName("Max Heap Memory")
                .withDescription("Displays the maximum amount of heap memory in bytes that can be used for memory management. " +
                        "This attribute displays -1 if the maximum heap memory size is undefined. " +
                        "This amount of memory is not guaranteed to be available for memory management if it is greater than " +
                        "the amount of committed memory. The Java virtual machine may fail to allocate memory even " +
                        "if the amount of used memory does not exceed this maximum size.")
                .withType(MetricType.GAUGE).withUnit(MetricUnits.BYTES).build(), gauge(memoryMXBean.getHeapMemoryUsage()::getMax));

        final List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
        garbageCollectorMXBeans.forEach(garbageCollectorMXBean -> {
            registry.register(Metadata.builder()
                    .withName("gc.total")
                    .withDisplayName("Garbage Collection Count")
                    .withDescription("Displays the total number of collections that have occurred." +
                            "This attribute lists -1 if the collection count is undefined for this collector.")
                    .withType(MetricType.COUNTER)
                    .withUnit(MetricUnits.NONE)
                    .build(),
                    counter(garbageCollectorMXBean::getCollectionCount),
                    new Tag("name", garbageCollectorMXBean.getName()));
            registry.register(Metadata.builder()
                    .withName("gc.time")
                    .withDisplayName("Garbage Collection Time")
                    .withDescription("Displays the approximate accumulated collection elapsed time in milliseconds." +
                            "This attribute displays -1 if the collection elapsed time is undefined for this collector." +
                            "The Java virtual machine implementation may use a high resolution timer to measure the elapsed time." +
                            "This attribute may display the same value even if the collection count has been incremented if" +
                            "the collection elapsed time is very short.")
                    .withType(MetricType.GAUGE)
                    .withUnit(MetricUnits.MILLISECONDS)
                    .build(),
                    gauge(garbageCollectorMXBean::getCollectionTime),
                    new Tag("name", garbageCollectorMXBean.getName()));
        });
    }

    private Gauge<Long> gauge(final LongSupplier supplier) {
        return new Gauge<Long>() {
            @Override
            @JsonbTransient
            public Long getValue() {
                return supplier.getAsLong();
            }
        };
    }

    private Counter counter(final LongSupplier supplier) {
        return new Counter() {
            @Override
            public void inc() {
                // no-op
            }

            @Override
            public void inc(final long n) {
                // no-op
            }

            @Override
            public long getCount() {
                return supplier.getAsLong();
            }
        };
    }
}
