package org.bench4q.monitor.model;

import java.beans.Transient;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.bench4q.monitor.service.GetSigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.Swap;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.Mem;

import com.google.gson.annotations.Expose;

@XmlRootElement(name = "Memory")
public class MemoryModel {
	@Expose
	private long pagesPerSecond;
	@Expose
	private long pagesInputPerSecond;
	@Expose
	private long pagesOutputPerSecond;
	@Expose
	private long availableKiloBytes;
	@Expose
	private long totalKiloBytes;
	@Expose
	private double memoryUsedPercent;
	@Expose
	private double swapKiloBytes;
	@Expose
	private double swapFreeKiloBytes;
	private Sigar sigar = GetSigar.getSigar();
	private Swap swap;
	private Mem mem;

	public static void main(String[] args) throws SigarException {
		MemoryModel model = new MemoryModel();
		System.out.println("PagesRate: " + model.getPagesPerSecond());
		System.out.println("PagesIn: " + model.getPagesInputPerSecond());
		System.out.println("PagesIn: " + model.getPagesOutputPerSecond());
		System.out.println("UsedPerc: " + model.getMemoryUsedPercent() + "%");
		System.out.println("Total: " + model.getTotalKiloBytes() + "kb");
		System.out.println("Aval: " + model.getAvailableKiloBytes() + "kb");
		System.out.println("swap total:" + model.getSwapKiloBytes() + "kb");
		System.out.println("swap free :" + model.getSwapFreeKiloBytes() + "kb");
	}

	public MemoryModel() throws SigarException {
		this.getPagesInputPerSecond();
		this.getPagesOutputPerSecond();
		this.getPagesPerSecond();
		this.getMemoryUsedPercent();
		this.getAvailableKiloBytes();
		this.getTotalKiloBytes();
		this.setSwapKiloBytes();
		this.setSwapFreeKiloBytes();
	}

	@XmlElement
	public long getPagesPerSecond() throws SigarException {
		setPagesPerSecond(getPagesInputPerSecond() + getPagesOutputPerSecond());
		return pagesPerSecond;
	}

	private void setPagesPerSecond(long pagesPerSecond) {
		this.pagesPerSecond = pagesPerSecond;
	}

	@XmlElement
	public long getPagesInputPerSecond() throws SigarException {
		swap = sigar.getSwap();
		setPagesInputPerSecond(swap.getPageIn());
		return pagesInputPerSecond;
	}

	private void setPagesInputPerSecond(long pagesInputPerSecond) {
		this.pagesInputPerSecond = pagesInputPerSecond;
	}

	@XmlElement
	public long getPagesOutputPerSecond() throws SigarException {
		swap = sigar.getSwap();
		setPagesOutputPerSecond(swap.getPageOut());
		return pagesOutputPerSecond;
	}

	private void setPagesOutputPerSecond(long pagesOutputPerSecond) {
		this.pagesOutputPerSecond = pagesOutputPerSecond;
	}

	@XmlElement
	public long getAvailableKiloBytes() throws SigarException {
		mem = sigar.getMem();
		setAvailableKiloBytes(mem.getActualFree() / 1024L);
		return availableKiloBytes;
	}

	private void setAvailableKiloBytes(long availableKiloBytes) {
		this.availableKiloBytes = availableKiloBytes;
	}

	@XmlElement
	public long getTotalKiloBytes() throws SigarException {
		mem = sigar.getMem();
		setTotalKiloBytes(mem.getTotal() / 1024L);
		return totalKiloBytes;
	}

	private void setTotalKiloBytes(long totalKiloBytes) {
		this.totalKiloBytes = totalKiloBytes;
	}

	@XmlElement
	public double getMemoryUsedPercent() throws SigarException {
		mem = sigar.getMem();
		long temp = Math.round(mem.getUsedPercent() * 100);
		setMemoryUsedPercent(temp / 100.0);
		return this.memoryUsedPercent;
	}

	private void setMemoryUsedPercent(double memoryUsedPercent) {
		this.memoryUsedPercent = memoryUsedPercent;
	}

	@XmlElement
	public double getSwapKiloBytes() {
		return swapKiloBytes;
	}

	private void setSwapKiloBytes() {
		this.swapKiloBytes = this.swap.getTotal() / 1024L;
	}

	@XmlElement
	public double getSwapFreeKiloBytes() {
		return swapFreeKiloBytes;
	}

	private void setSwapFreeKiloBytes() {
		this.swapFreeKiloBytes = this.swap.getFree() / 1024L;
	}

	@Transient
	public Sigar getSigar() {
		return sigar;
	}

	public void setSigar(Sigar sigar) {
		this.sigar = sigar;
	}

	@Transient
	public Swap getSwap() {
		return swap;
	}

	public void setSwap(Swap swap) {
		this.swap = swap;
	}

	@Transient
	public Mem getMem() {
		return mem;
	}

	public void setMem(Mem mem) {
		this.mem = mem;
	}

}
