package eu.dnetlib.services;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;

/**
 * This bean packages the minimum information for describing a service running instance.
 */
public class ServiceRunningInstance {

	private String serviceId;
	private String baseUrl;
	private long freeDiskSpace = 0;
	private long totalDiskSpace = 0;
	private long freeMemory = 0;
	private long totalMemory = 0;
	private long maxMemory = 0;
	private long usedMemory = 0;
	private long numberOfProcessors = 0;
	private double sysLoadAvg = 0;

	public static ServiceRunningInstance newInstance(final String serviceId, final String baseUrl, final String baseDir) {
		return newInstance(new ServiceRunningInstance(), serviceId, baseUrl, baseDir);
	}

	protected static <T extends ServiceRunningInstance> T newInstance(final T instance,
			final String serviceId,
			final String baseUrl,
			final String baseDir) {

		instance.setServiceId(serviceId);
		instance.setBaseUrl(baseUrl);

		final File f = new File(baseDir);
		instance.setFreeDiskSpace(bytesToMegaBytes(f.getFreeSpace()));
		instance.setTotalDiskSpace(bytesToMegaBytes(f.getTotalSpace()));

		final Runtime runtime = Runtime.getRuntime();
		instance.setFreeMemory(bytesToMegaBytes(runtime.freeMemory()));
		instance.setTotalMemory(bytesToMegaBytes(runtime.totalMemory()));
		instance.setMaxMemory(bytesToMegaBytes(runtime.maxMemory()));
		instance.setUsedMemory(bytesToMegaBytes(runtime.totalMemory() - runtime.freeMemory()));

		final OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
		instance.setNumberOfProcessors(osBean.getAvailableProcessors());
		instance.setSysLoadAvg(osBean.getSystemLoadAverage());

		return instance;
	}

	public ServiceRunningInstance() {}

	private static final long bytesToMegaBytes(final long n) {
		return n / 1_048_576;
	}

	public String getServiceId() {
		return serviceId;
	}

	public void setServiceId(final String serviceId) {
		this.serviceId = serviceId;
	}

	public String getBaseUrl() {
		return baseUrl;
	}

	public void setBaseUrl(final String baseUrl) {
		this.baseUrl = baseUrl;
	}

	public long getFreeDiskSpace() {
		return freeDiskSpace;
	}

	public void setFreeDiskSpace(final long freeDiskSpace) {
		this.freeDiskSpace = freeDiskSpace;
	}

	public long getTotalDiskSpace() {
		return totalDiskSpace;
	}

	public void setTotalDiskSpace(final long totalDiskSpace) {
		this.totalDiskSpace = totalDiskSpace;
	}

	public long getFreeMemory() {
		return freeMemory;
	}

	public void setFreeMemory(final long freeMemory) {
		this.freeMemory = freeMemory;
	}

	public long getTotalMemory() {
		return totalMemory;
	}

	public void setTotalMemory(final long totalMemory) {
		this.totalMemory = totalMemory;
	}

	public long getMaxMemory() {
		return maxMemory;
	}

	public void setMaxMemory(final long maxMemory) {
		this.maxMemory = maxMemory;
	}

	public long getUsedMemory() {
		return usedMemory;
	}

	public void setUsedMemory(final long usedMemory) {
		this.usedMemory = usedMemory;
	}

	public long getNumberOfProcessors() {
		return numberOfProcessors;
	}

	public void setNumberOfProcessors(final long numberOfProcessors) {
		this.numberOfProcessors = numberOfProcessors;
	}

	public double getSysLoadAvg() {
		return sysLoadAvg;
	}

	public void setSysLoadAvg(final double sysLoadAvg) {
		this.sysLoadAvg = sysLoadAvg;
	}

}
