package com.henrypump.poc;

import static java.lang.Math.abs;

/**
 * Created by patrickjmcd on 2/3/17.
 */
public class Measurement {
    private String tagName;
    private double currentValue;
    private double lastValue;
    private double average;
    private double total;
    private double dailyMax;
    private double dailyMin;
    private double[] totalHistory = new double[30];
    private double[] averageHistory = new double[30];
    private long numMeasurements;
    private boolean storeInDatabase;
    private double lastSentValue;
    private double sendDelta;
    private Database db;
    private long lastSentTimestamp;
    private long sendTimeDelta;

    Measurement(String tagName, boolean storeInDatabase, Database db, double sendDelta, long sendTimeDelta){
        this.tagName = tagName;
        average = 0;
        total = 0;
        numMeasurements = 0;
        dailyMax = Double.MIN_VALUE;
        dailyMin = Double.MAX_VALUE;

        // Database code
        this.storeInDatabase = storeInDatabase;
        this.db = db;
        this.sendDelta = sendDelta;
        this.lastSentValue = 0.0;
        this.sendTimeDelta = sendTimeDelta;
    }

    Measurement(String tagName, boolean storeInDatabase){
        this.tagName = tagName;
        average = 0;
        total = 0;
        numMeasurements = 0;
        dailyMax = Double.MIN_VALUE;
        dailyMin = Double.MAX_VALUE;

        // Database code
        this.storeInDatabase = storeInDatabase;
    }

    public double getCurrentValue() {
        return currentValue;
    }

    public double getLastValue() {
        return lastValue;
    }

    public double getAverage() {
        return average;
    }

    public double getTotal() {
        return total;
    }

    public long getNumMeasurements() {
        return numMeasurements;
    }

    public String getTagName() {
        return tagName;
    }

    public double getDailyMax() {
        return dailyMax;
    }

    public double getDailyMin() {
        return dailyMin;
    }

    public void update(double value)
    {
        long currentTimestamp = System.currentTimeMillis();
        lastValue = currentValue;
        currentValue = value;

        numMeasurements = numMeasurements + 1;
        average = average * (((float)numMeasurements - 1)/(float)numMeasurements) + (currentValue / (float)numMeasurements);
        total = total + value;

        dailyMax = Math.max(dailyMax, currentValue);
        dailyMin = Math.min(dailyMin, currentValue);

        if(storeInDatabase){
            if(abs(currentValue - lastSentValue) > sendDelta ||
                    currentTimestamp - lastSentTimestamp > (sendTimeDelta  * 1000)){
                long l = db.newMeasurement(this);
                lastSentValue = currentValue;
            }
        }
    }

    public void endOfDay(){
        if (storeInDatabase){
            db.newDailyTotal(this);
        }
        for(int i = 28; i >= 0; i--){
            totalHistory[i] = totalHistory[i+1];
            averageHistory[i] = averageHistory[i+1];
        }

        totalHistory[0] = total;
        averageHistory[0] = average;

        total = 0;
        average = 0;
        dailyMax = Double.MIN_VALUE;
        dailyMin = Double.MAX_VALUE;
    }



}
