/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package vut.msa.monitor.system;

import java.io.Serializable;
import java.util.logging.Level;
import org.apache.log4j.Logger;
import org.hyperic.sigar.DirUsage;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.Uptime;

/**
 * Trieda sluzi na ziskanie informacii o zariadeni. Tieto informacie sluzia na sledovanie
 * stavu klienta. Vyuziva nastroj SIGAR. Narozdiel od ServerInformation, je potrebne
 * aby tato trieda bola serializovatelna a prenesitelna tak cez siet, aby si server
 * ulozil udaje do databazy. Vyuziva nastroj SIGAR, ten vsak serializovatelny nie je
 * a preto su informacie ulozene do premennych triedy a tie su prenesene.
 */
public class SystemInformation implements Serializable {

    private static final Logger log = Logger.getLogger(FileSystemInformation.class);
    private static final String DEFAULT_PATH = "C:\\Documents";


    private transient Sigar sigar;
    private transient Mem memoryInformation;

    // System information
    private double uptime;
    private long memoryRAM;
    private double memoryUsedPerc;

    private long totalDisk;
    private long usedDisk;
    private long freeDisk;

    private int documentsCount;
    private long documentsSize;

    public SystemInformation() {

        try {
            sigar = new Sigar();
            Sigar.load();

            //V sekundach, postacuje na 68 rokov
            Uptime upt = new Uptime();
            upt.gather(sigar);
            uptime = upt.getUptime();

            fillSystemInformations();
        } catch (SigarException ex) {
            log.error(ex.getMessage());
        }
    }


    public long getFreeDisk() { return freeDisk; }

    public long getTotalDisk() { return totalDisk; }

    public long getUsedDisk() { return usedDisk; }

    public long getMemoryRAM() { return memoryRAM; }

    public int getDocumentsCount() { return documentsCount; }

    public long getDocumentsSize() { return documentsSize; }

    public double getMemoryUsedPerc() { return memoryUsedPerc; }
    /**
     * Funkcia vráti čas od spustenia systému (Uptime) v sekundách.
     *
     * @return čas v sekundách
     * @throws SigarException
     */
    public double getUptime() throws SigarException {      
        return uptime;
    }

    /**
     * Metoda naformatuje cas behu systemu z milisekund na format "xx dní, xx hodín, xx min."
     * @param uptime
     * @return
     */
    public String getFormatedUptime(int uptime) {

        int days = uptime/86400;
        int temp = uptime % 86400;
        int hours = temp/3600;
        int minutes = (temp % 3600) /60;
        return days + " dní, " + hours + " hodín, " + minutes + "min.";
    }

    /**
     * Funkcia vrati objekt Mem, ktory poskytuje informacie o pamati.
     *
     * @return objekt Mem
     * @throws SigarException
     * @see org.hyperic.sigar.Mem
     */
    public Mem getMemoryInfo() throws SigarException {

        memoryInformation = new Mem();
        memoryInformation.gather(sigar);

        return memoryInformation;
    }

    /**
     * Funkcia vrati objekt DirUsage, ktory poskytuje informacie o adresari.
     *
     * @param path cesta k adresaru s dokumentami
     * @return  objekt DirUsage
     * @throws SigarException
     * @see org.hyperic.sigar.DirUsage;
     */
    public DirUsage getDocumentsDir(String path) throws SigarException {
        DirUsage dir = new DirUsage();
        dir.gather(sigar, path);

        return dir;
    }

    /**
     * Funkcia vrati objekt DirUsage, ktory poskytuje informacie o adresari.
     * Pouzije standardnu cestu k adresaru C:\Documents
     *
     * @return  objekt DirUsage
     * @throws SigarException
     * @see org.hyperic.sigar.DirUsage;
     */
    public DirUsage getDocumentsDir() throws SigarException {
        return this.getDocumentsDir(DEFAULT_PATH);
    }

    /**
     * Funkcia vrati objekt FileSystemInformation, ktory sluzi na poskytovanie
     * informacii o suborovom systeme.
     *
     * @return objet FileSystemInformation
     * @throws SigarException
     * @see vut.msa.monitor.system.FileSystemInformation
     */
    public FileSystemInformation getFileSystemInfo() throws SigarException {
        return new FileSystemInformation(this.sigar);
    }

    //Iba na testovanie
    public static void main(String[] args) {

        SystemInformation info = new SystemInformation();

        try {
            System.out.println ("System uptime: " + info.getFormatedUptime((int)info.getUptime()));
            System.out.println ("Pocet dokumentov: " + info.getDocumentsDir().getFiles());
            System.out.println ("Velkost adresara: " + info.getDocumentsDir().getDiskUsage()/(1024*1024) + " MB");
            System.out.println ("System free memory: " + info.getMemoryInfo().getUsedPercent());

            System.out.println ("Disk C total : " + info.getFileSystemInfo().getFileSystemUsage("D:\\").getTotal());
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
    }

    /**
     * Funkcia naplni informacie o systeme. Sluzi len na prenos medzi strojmi, 
     * nakolko Sigar nie je mozne preniest (nie je serializovatelny).
     * 
     * @throws SigarException
     */
    private void fillSystemInformations() throws SigarException {

        this.memoryRAM = this.getMemoryInfo().getRam();
        this.memoryUsedPerc = this.getMemoryInfo().getUsedPercent();

        this.totalDisk = this.getFileSystemInfo().getFileSystemUsage("C:\\").getTotal();
        this.usedDisk = this.getFileSystemInfo().getFileSystemUsage("C:\\").getUsed();
        this.freeDisk = totalDisk - usedDisk;

        DirUsage dir = getDocumentsDir();
        this.documentsCount = (int) dir.getFiles();
        this.documentsSize = dir.getDiskUsage();
        
    }
}
