'use strict';

if (!Array.prototype.includes)
    Array.prototype.includes = function (value) { return this.indexOf(value) >= 0; }

class MeasurementSet {
    constructor(platformId, metricId, lastModified)
    {
        this._platformId = platformId;
        this._metricId = metricId;
        this._lastModified = +lastModified;

        this._sortedClusters = [];
        this._primaryClusterEndTime = null;
        this._clusterCount = null;
        this._clusterStart = null;
        this._clusterSize = null;
        this._allFetches = {};
        this._callbackMap = new Map;
        this._primaryClusterPromise = null;
        this._segmentationCache = new Map;
    }

    platformId() { return this._platformId; }
    metricId() { return this._metricId; }

    static findSet(platformId, metricId, lastModified)
    {
        if (!this._set)
            this._set = {};
        var key = platformId + '-' + metricId;
        if (!this._set[key])
            this._set[key] = new MeasurementSet(platformId, metricId, lastModified);
        return this._set[key];
    }

    findClusters(startTime, endTime)
    {
        var clusterStart = this._clusterStart;
        var clusterSize = this._clusterSize;

        var clusters = [];
        var clusterEnd = clusterStart + Math.floor(Math.max(0, startTime - clusterStart) / clusterSize) * clusterSize;

        var lastClusterEndTime = this._primaryClusterEndTime;
        var firstClusterEndTime = lastClusterEndTime - clusterSize * (this._clusterCount - 1);
        do {
            clusterEnd += clusterSize;
            if (firstClusterEndTime <= clusterEnd && clusterEnd <= this._primaryClusterEndTime)
                clusters.push(clusterEnd);
        } while (clusterEnd < endTime);

        return clusters;
    }

    fetchBetween(startTime, endTime, callback, noCache)
    {
        if (noCache) {
            this._primaryClusterPromise = null;
            this._allFetches = {};
        }
        if (!this._primaryClusterPromise)
            this._primaryClusterPromise = this._fetchPrimaryCluster(noCache);
        var self = this;
        this._primaryClusterPromise.catch(callback);
        return this._primaryClusterPromise.then(function () {
            self._allFetches[self._primaryClusterEndTime] = self._primaryClusterPromise;
            return Promise.all(self.findClusters(startTime, endTime).map(function (clusterEndTime) {
                return self._ensureClusterPromise(clusterEndTime, callback);
            }));
        });
    }

    _ensureClusterPromise(clusterEndTime, callback)
    {
        if (!this._callbackMap.has(clusterEndTime))
            this._callbackMap.set(clusterEndTime, new Set);
        var callbackSet = this._callbackMap.get(clusterEndTime);
        callbackSet.add(callback);

        var promise = this._allFetches[clusterEndTime];
        if (promise)
            promise.then(callback, callback);
        else {
            promise = this._fetchSecondaryCluster(clusterEndTime);
            for (var existingCallback of callbackSet)
                promise.then(existingCallback, existingCallback);
            this._allFetches[clusterEndTime] = promise;
        }

        return promise;
    }

    _constructUrl(useCache, clusterEndTime)
    {
        if (!useCache) {
            return `../api/measurement-set?platform=${this._platformId}&metric=${this._metricId}`;
        }
        var url;
        url = `../data/measurement-set-${this._platformId}-${this._metricId}`;
        if (clusterEndTime)
            url += '-' + +clusterEndTime;
        url += '.json';
        return url;
    }

    _fetchPrimaryCluster(noCache)
    {
        var self = this;
        if (noCache) {
            return RemoteAPI.getJSONWithStatus(self._constructUrl(false, null)).then(function (data) {
                self._didFetchJSON(true, data);
            });
        }

        return RemoteAPI.getJSONWithStatus(self._constructUrl(true, null)).then(function (data) {
            if (+data['lastModified'] < self._lastModified)
                return RemoteAPI.getJSONWithStatus(self._constructUrl(false, null));
            return data;
        }).catch(function (error) {
            if(error == 404)
                return RemoteAPI.getJSONWithStatus(self._constructUrl(false, null));
            return Promise.reject(error);
        }).then(function (data) {
            self._didFetchJSON(true, data);
        });
    }

    _fetchSecondaryCluster(endTime)
    {
        var self = this;
        return RemoteAPI.getJSONWithStatus(self._constructUrl(true, endTime)).then(function (data) {
            self._didFetchJSON(false, data);
        });
    }

    _didFetchJSON(isPrimaryCluster, response, clusterEndTime)
    {
        if (isPrimaryCluster) {
            this._primaryClusterEndTime = response['endTime'];
            this._clusterCount = response['clusterCount'];
            this._clusterStart = response['clusterStart'];
            this._clusterSize = response['clusterSize'];
        } else
            console.assert(this._primaryClusterEndTime);

        this._addFetchedCluster(new MeasurementCluster(response));
    }

    _addFetchedCluster(cluster)
    {
        for (var clusterIndex = 0; clusterIndex < this._sortedClusters.length; clusterIndex++) {
            var startTime = this._sortedClusters[clusterIndex].startTime();
            if (cluster.startTime() <= startTime) {
                this._sortedClusters.splice(clusterIndex, startTime == cluster.startTime() ? 1 : 0, cluster);
                return;
            }
        }
        this._sortedClusters.push(cluster);
    }

    hasFetchedRange(startTime, endTime)
    {
        console.assert(startTime < endTime);
        let foundStart = false;
        let previousEndTime = null;
        endTime = Math.min(endTime, this._primaryClusterEndTime);
        for (var cluster of this._sortedClusters) {
            const containsStart = cluster.startTime() <= startTime && startTime <= cluster.endTime();
            const containsEnd = cluster.startTime() <= endTime && endTime <= cluster.endTime();
            const preceedingClusterIsMissing = previousEndTime !== null && previousEndTime != cluster.startTime();
            if (containsStart && containsEnd)
                return true;
            if (containsStart)
                foundStart = true;
            if (foundStart && preceedingClusterIsMissing)
                return false;
            if (containsEnd)
                return foundStart; // Return true iff there were not missing clusters from the one that contains startTime
            previousEndTime = cluster.endTime();
        }
        return false; // Didn't find a cluster that contains startTime or endTime
    }

    fetchedTimeSeries(configType, includeOutliers, extendToFuture)
    {
        Instrumentation.startMeasuringTime('MeasurementSet', 'fetchedTimeSeries');

        // FIXME: Properly construct TimeSeries.
        var series = new TimeSeries();
        var idMap = {};
        for (var cluster of this._sortedClusters)
            cluster.addToSeries(series, configType, includeOutliers, idMap);

        if (extendToFuture)
            series.extendToFuture();

        Instrumentation.endMeasuringTime('MeasurementSet', 'fetchedTimeSeries');

        return series;
    }

    fetchSegmentation(segmentationName, parameters, configType, includeOutliers, extendToFuture)
    {
        var cacheMap = this._segmentationCache.get(configType);
        if (!cacheMap) {
            cacheMap = new WeakMap;
            this._segmentationCache.set(configType, cacheMap);
        }

        var timeSeries = new TimeSeries;
        var idMap = {};
        var promises = [];
        for (var cluster of this._sortedClusters) {
            var clusterStart = timeSeries.length();
            cluster.addToSeries(timeSeries, configType, includeOutliers, idMap);
            var clusterEnd = timeSeries.length();
            promises.push(this._cachedClusterSegmentation(segmentationName, parameters, cacheMap,
                cluster, timeSeries, clusterStart, clusterEnd, idMap));
        }
        if (!timeSeries.length())
            return Promise.resolve(null);

        var self = this;
        return Promise.all(promises).then(function (clusterSegmentations) {
            var segmentationSeries = [];
            var addSegment = function (startingPoint, endingPoint) {
                var value = Statistics.mean(timeSeries.valuesBetweenRange(startingPoint.seriesIndex, endingPoint.seriesIndex));
                segmentationSeries.push({value: value, time: startingPoint.time, seriesIndex: startingPoint.seriesIndex, interval: function () { return null; }});
                segmentationSeries.push({value: value, time: endingPoint.time, seriesIndex: endingPoint.seriesIndex, interval: function () { return null; }});
            };

            var startingIndex = 0;
            for (var segmentation of clusterSegmentations) {
                for (var endingIndex of segmentation) {
                    addSegment(timeSeries.findPointByIndex(startingIndex), timeSeries.findPointByIndex(endingIndex));
                    startingIndex = endingIndex;
                }
            }
            if (extendToFuture)
                timeSeries.extendToFuture();
            addSegment(timeSeries.findPointByIndex(startingIndex), timeSeries.lastPoint());
            return segmentationSeries;
        });
    }

    _cachedClusterSegmentation(segmentationName, parameters, cacheMap, cluster, timeSeries, clusterStart, clusterEnd, idMap)
    {
        var cache = cacheMap.get(cluster);
        if (cache && this._validateSegmentationCache(cache, segmentationName, parameters)) {
            var segmentationByIndex = new Array(cache.segmentation.length);
            for (var i = 0; i < cache.segmentation.length; i++) {
                var id = cache.segmentation[i];
                if (!(id in idMap))
                    return null;
                segmentationByIndex[i] = idMap[id];
            }
            return Promise.resolve(segmentationByIndex);
        }

        var clusterValues = timeSeries.valuesBetweenRange(clusterStart, clusterEnd);
        return this._invokeSegmentationAlgorithm(segmentationName, parameters, clusterValues).then(function (segmentationInClusterIndex) {
            // Remove cluster start/end as segmentation points. Otherwise each cluster will be placed into its own segment. 
            var segmentation = segmentationInClusterIndex.slice(1, -1).map(function (index) { return clusterStart + index; });
            var cache = segmentation.map(function (index) { return timeSeries.findPointByIndex(index).id; });
            cacheMap.set(cluster, {segmentationName: segmentationName, segmentationParameters: parameters.slice(), segmentation: cache});
            return segmentation;
        });
    }

    _validateSegmentationCache(cache, segmentationName, parameters)
    {
        if (cache.segmentationName != segmentationName)
            return false;
        if (!!cache.segmentationParameters != !!parameters)
            return false;
        if (parameters) {
            if (parameters.length != cache.segmentationParameters.length)
                return false;
            for (var i = 0; i < parameters.length; i++) {
                if (parameters[i] != cache.segmentationParameters[i])
                    return false;
            }
        }
        return true;
    }

    _invokeSegmentationAlgorithm(segmentationName, parameters, timeSeriesValues)
    {
        var args = [timeSeriesValues].concat(parameters || []);

        var timeSeriesIsShortEnoughForSyncComputation = timeSeriesValues.length < 100;
        if (timeSeriesIsShortEnoughForSyncComputation) {
            Instrumentation.startMeasuringTime('_invokeSegmentationAlgorithm', 'syncSegmentation');
            var segmentation = Statistics[segmentationName].apply(timeSeriesValues, args);
            Instrumentation.endMeasuringTime('_invokeSegmentationAlgorithm', 'syncSegmentation');
            return Promise.resolve(segmentation);
        }

        var task = new AsyncTask(segmentationName, args);
        return task.execute().then(function (response) {
            Instrumentation.reportMeasurement('_invokeSegmentationAlgorithm', 'workerStartLatency', 'ms', response.startLatency);
            Instrumentation.reportMeasurement('_invokeSegmentationAlgorithm', 'workerTime', 'ms', response.workerTime);
            Instrumentation.reportMeasurement('_invokeSegmentationAlgorithm', 'totalTime', 'ms', response.totalTime);
            return response.result;
        });
    }

}

if (typeof module != 'undefined')
    module.exports.MeasurementSet = MeasurementSet;
