package pro.panopticon.client.sensor.impl;

import com.amazonaws.services.cloudwatch.model.StandardUnit;
import pro.panopticon.client.model.Measurement;
import pro.panopticon.client.sensor.Sensor;
import pro.panopticon.client.util.SystemStatus;

import java.util.ArrayList;
import java.util.List;

public class MemorySensor implements Sensor {

    private static final long BYTES_IN_MB = 1024 * 1024;

    @Override
    public List<Measurement> measure() {
        SystemStatus s = new SystemStatus();

        List<Measurement> measurements = new ArrayList<>();

        putMemoryStatus(measurements, "mem.heap.now", s.heapUsed(), s.heapMax());
        putMemoryStatus(measurements, "mem.heap.lastGC", s.heapAfterGC(), s.heapMax());

        return measurements;
    }

    private void putMemoryStatus(List<Measurement> measurements, String key, long used, long max) {

        if (max == 0 || used == -1) {
            return;
        }
        long percentUsed = used / (max / 100);
        long percentLeft = 100 - percentUsed;

        String displayValue = toMB(used) + " of " + toMB(max) + " MB (" + percentUsed + "%)";

        measurements.add(new Measurement(key, status(percentLeft), displayValue, new Measurement.CloudwatchValue(percentUsed, StandardUnit.Percent)));
    }

    private String status(long percentLeft) {
        if (percentLeft < 5) {
            return "ERROR";
        } else if (percentLeft < 25) {
            return "WARN";
        } else {
            return "INFO";
        }
    }

    private long toMB(final long bytes) {
        return bytes / BYTES_IN_MB;
    }
}

@@ -396,16 +396,515 @@
  1024;%0A%0A
+    private final int warnLimitNow;%0A    private final int errorLimitNow;%0A    private final int warnLimitHeap;%0A    private final int errorLimitHeap;%0A%0A    public MemorySensor() %7B%0A        this(85, 95, 75, 95);%0A    %7D%0A%0A    public MemorySensor(int warnLimitNow, int errorLimitNow, int warnLimitHeap, int errorLimitHeap) %7B%0A        this.warnLimitNow = warnLimitNow;%0A        this.errorLimitNow = errorLimitNow;%0A        this.warnLimitHeap = warnLimitHeap;%0A        this.errorLimitHeap = errorLimitHeap;%0A    %7D%0A%0A
     @Ove
@@ -1136,16 +1136,45 @@
 eapMax()
+, warnLimitNow, errorLimitNow
 );%0A     
@@ -1253,16 +1253,47 @@
 eapMax()
+, warnLimitHeap, errorLimitHeap
 );%0A%0A    
@@ -1420,16 +1420,47 @@
 long max
+, int warnLimit, int errorLimit
 ) %7B%0A%0A   
@@ -1574,54 +1574,8 @@
 00);
-%0A        long percentLeft = 100 - percentUsed;
 %0A%0A  
@@ -1727,19 +1727,42 @@
 (percent
-Lef
+Used, warnLimit, errorLimi
 t), disp
@@ -1886,19 +1886,50 @@
  percent
-Lef
+Used, int warnLimit, int errorLimi
 t) %7B%0A   
@@ -1948,16 +1948,25 @@
 cent
-Left %3C 5
+Used %3E errorLimit
 ) %7B%0A
@@ -2023,17 +2023,24 @@
 cent
-Left %3C 25
+Used %3E warnLimit
 ) %7B%0A

Make limits of memorysensor configurable