package ru.r2cloud.metrics;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

import ru.r2cloud.R2Cloud;
import ru.r2cloud.uitl.Configuration;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.MetricRegistry.MetricSupplier;
import com.codahale.metrics.SharedMetricRegistries;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.codahale.metrics.health.SharedHealthCheckRegistries;

public class Metrics {

	private static final Logger LOG = Logger.getLogger(R2Cloud.class.getName());
	public static final MetricRegistry REGISTRY = SharedMetricRegistries.getOrCreate("r2cloud");
	public static final HealthCheckRegistry HEALTH_REGISTRY = SharedHealthCheckRegistries.getOrCreate("r2cloud");

	private RRD4JReporter reporter;
	private Sigar sigar;
	private final Configuration config;

	public Metrics(Configuration config) {
		this.config = config;
	}

	@SuppressWarnings("rawtypes")
	public void start() {
		if (new File("/sys/class/thermal/thermal_zone0/temp").exists()) {
			REGISTRY.gauge("temperature", new MetricSupplier<Gauge>() {

				@Override
				public Gauge<?> newMetric() {
					return new FormattedGauge<Double>(MetricFormat.NORMAL) {

						@Override
						public Double getValue() {
							try (BufferedReader fis = new BufferedReader(new FileReader("/sys/class/thermal/thermal_zone0/temp"))) {
								String line = fis.readLine();
								if (line == null) {
									return null;
								}
								return ((double) Long.valueOf(line) / 1000);
							} catch (Exception e) {
								LOG.log(Level.SEVERE, "unable to get temp: " + e.getMessage());
								return null;
							}
						}
					};
				}
			});
		} else {
			LOG.info("temperature metric is not available");
		}

		REGISTRY.gauge("heap", new MetricSupplier<Gauge>() {
			@Override
			public Gauge<?> newMetric() {
				return new FormattedGauge<Long>(MetricFormat.BYTES) {

					@Override
					public Long getValue() {
						return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
					}
				};
			}
		});

		try {
			sigar = new Sigar();
			REGISTRY.gauge("load-average", new MetricSupplier<Gauge>() {
				@Override
				public Gauge<?> newMetric() {
					return new FormattedGauge<Double>(MetricFormat.NORMAL) {

						@Override
						public Double getValue() {
							try {
								return sigar.getLoadAverage()[0];
							} catch (SigarException e) {
								return null;
							}
						}
					};
				}
			});
			LOG.info("SIGAR library was loaded");
		} catch (UnsatisfiedLinkError linkError) {
			LOG.info("Could not initialize SIGAR library: " + linkError.getMessage());
		}

		reporter = new RRD4JReporter(config, REGISTRY);
		reporter.start();
		LOG.info("metrics started");
	}

	public void stop() {
		if (sigar != null) {
			sigar.close();
		}
		if (reporter != null) {
			reporter.close();
		}
	}
}

@@ -2650,16 +2650,392 @@
 %0A%09%09%09%7D);%0A
+%09%09%09REGISTRY.gauge(%22ram-used%22, new MetricSupplier%3CGauge%3E() %7B%0A%09%09%09%09@Override%0A%09%09%09%09public Gauge%3C?%3E newMetric() %7B%0A%09%09%09%09%09return new FormattedGauge%3CDouble%3E(MetricFormat.NORMAL) %7B%0A%0A%09%09%09%09%09%09@Override%0A%09%09%09%09%09%09public Double getValue() %7B%0A%09%09%09%09%09%09%09try %7B%0A%09%09%09%09%09%09%09%09return sigar.getMem().getUsedPercent();%0A%09%09%09%09%09%09%09%7D catch (SigarException e) %7B%0A%09%09%09%09%09%09%09%09return null;%0A%09%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%7D;%0A%09%09%09%09%7D%0A%09%09%09%7D);%0A
 %09%09%09LOG.i

monitor ram