/**
 * Copyright 2016 the WHATAP project authors. All rights reserved.
 * Use of this source code is governed by a license that
 * can be found in the LICENSE file.
 */

var ValueEnum       = require('./valueenum'),
    SummaryValue    = require('./summary-value'),
    Long            = require('long');

function LongSummary() {
    SummaryValue.call(this);

    this.sum = Long.fromInt(0);
    this.count = 0;
    this.min = Long.fromInt(0);
    this.max = Long.fromInt(0);
}

LongSummary.prototype = new SummaryValue();
LongSummary.prototype.constructor = LongSummary;
LongSummary.prototype.getValueType = function() {
    return ValueEnum.LONG_SUMMARY;
};
LongSummary.prototype.write = function(dout) {
    dout.writeLong(this.sum);
    dout.writeInt(this.count);
    dout.writeLong(this.min);
    dout.writeLong(this.max);
};
LongSummary.prototype.read = function(din) {
    this.sum = din.readLong();
    this.count = din.readInt();
    this.min = din.readLong();
    this.max = din.readLong();
    return this;
};
LongSummary.prototype.toObject = function() {
    return this;
};
LongSummary.prototype.add = function(value) {
    if(value == null) {
        return this;
    }

    if(value instanceof SummaryValue) {
        return this.addObject(value);
    }

    if(this.count === 0) {
        this.sum = Long.fromNumber(value);
        this.count = 1;
        this.max = Long.fromNumber(value);
        this.min = Long.fromNumber(value);
    } else {
        var longVal = Long.fromNumber(value);
        this.sum.add(longVal);
        this.count++;
        this.max = this.max.compare(longVal) < 0 ? Long.fromNumber(value) : this.max;
        this.min = this.min.compare(longVal) > 0 ? Long.fromNumber(value) : this.min;
    }
    return this;
};
LongSummary.prototype.addCount = function(){
    this.count++;
};
LongSummary.prototype.addObject = function (other) {
    if(other.getCount() === 0) {
        return this;
    }
    this.count += other.getCount();
    this.sum.add(other.doubleSum());
    var longMax = Long.fromNumber(other.doubleMax());
    this.max = this.max.compare(longMax) < 0 ? longMax : this.max;
    var longMin = Long.fromNumber(other.doubleMin());
    this.min = this.min.compare(longMin) > 0 ? longMin : this.min;
};
LongSummary.prototype.longSum = function() {
    return this.sum;
};
LongSummary.prototype.longMin = function() {
    return this.min;
};
LongSummary.prototype.longMax = function() {
    return this.max;
};
LongSummary.prototype.longAvg = function() {
    return this.sum.div(this.count);
};
LongSummary.prototype.doubleSum = function() {
    return this.sum.toNumber();
};
LongSummary.prototype.doubleMin = function() {
    return this.min.toNumber();
};
LongSummary.prototype.doubleMax = function() {
    return this.max.toNumber();
};
LongSummary.prototype.doubleAvg = function() {
    return this.longAvg().toNumber();
};
LongSummary.prototype.getCount = function() {
    return this.count;
};

module.exports = LongSummary;