package org.apache.cassandra.stress.util;
/*
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 */

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

// represents measurements taken over an interval of time
// used for both single timer results and merged timer results
public final class TimingInterval
{
    // nanos
    private final long start;
    private final long end;
    public final long maxLatency;
    public final long pauseLength;
    public final long pauseStart;
    public final long totalLatency;

    // discrete
    public final long partitionCount;
    public final long rowCount;
    public final long operationCount;
    public final long errorCount;

    final SampleOfLongs sample;

    public String toString()
    {
        return String.format("Start: %d end: %d maxLatency: %d pauseLength: %d pauseStart: %d totalLatency: %d" +
                             " pCount: %d rcount: %d opCount: %d errors: %d", start, end, maxLatency, pauseLength,
                             pauseStart, totalLatency, partitionCount, rowCount, operationCount, errorCount);
    }

    TimingInterval(long time)
    {
        start = end = time;
        maxLatency = totalLatency = 0;
        partitionCount = rowCount = operationCount = errorCount = 0;
        pauseStart = pauseLength = 0;
        sample = new SampleOfLongs(new long[0], 1d);
    }

    TimingInterval(long start, long end, long maxLatency, long pauseStart, long pauseLength, long partitionCount,
                   long rowCount, long totalLatency, long operationCount, long errorCount, SampleOfLongs sample)
    {
        this.start = start;
        this.end = Math.max(end, start);
        this.maxLatency = maxLatency;
        this.partitionCount = partitionCount;
        this.rowCount = rowCount;
        this.totalLatency = totalLatency;
        this.errorCount = errorCount;
        this.operationCount = operationCount;
        this.pauseStart = pauseStart;
        this.pauseLength = pauseLength;
        this.sample = sample;
    }

    // merge multiple timer intervals together
    static TimingInterval merge(Iterable<TimingInterval> intervals, int maxSamples, long start)
    {
        ThreadLocalRandom rnd = ThreadLocalRandom.current();
        long operationCount = 0, partitionCount = 0, rowCount = 0, errorCount = 0;
        long maxLatency = 0, totalLatency = 0;
        List<SampleOfLongs> latencies = new ArrayList<>();
        long end = 0;
        long pauseStart = 0, pauseEnd = Long.MAX_VALUE;
        for (TimingInterval interval : intervals)
        {
            if (interval != null)
            {
                end = Math.max(end, interval.end);
                operationCount += interval.operationCount;
                maxLatency = Math.max(interval.maxLatency, maxLatency);
                totalLatency += interval.totalLatency;
                partitionCount += interval.partitionCount;
                rowCount += interval.rowCount;
                errorCount += interval.errorCount;
                latencies.addAll(Arrays.asList(interval.sample));
                if (interval.pauseLength > 0)
                {
                    pauseStart = Math.max(pauseStart, interval.pauseStart);
                    pauseEnd = Math.min(pauseEnd, interval.pauseStart + interval.pauseLength);
                }
            }
        }

        if (pauseEnd < pauseStart || pauseStart <= 0)
        {
            pauseEnd = pauseStart = 0;
        }

        return new TimingInterval(start, end, maxLatency, pauseStart, pauseEnd - pauseStart, partitionCount, rowCount,
                                  totalLatency, operationCount, errorCount, SampleOfLongs.merge(rnd, latencies, maxSamples));

    }

    public double opRate()
    {
        return operationCount / ((end - start) * 0.000000001d);
    }

    public double adjustedRowRate()
    {
        return rowCount / ((end - (start + pauseLength)) * 0.000000001d);
    }

    public double partitionRate()
    {
        return partitionCount / ((end - start) * 0.000000001d);
    }

    public double rowRate()
    {
        return rowCount / ((end - start) * 0.000000001d);
    }

    public double meanLatency()
    {
        return (totalLatency / (double) operationCount) * 0.000001d;
    }

    public double maxLatency()
    {
        return maxLatency * 0.000001d;
    }

    public double medianLatency()
    {
        return sample.medianLatency();
    }

    // 0 < rank < 1
    public double rankLatency(float rank)
    {
        return sample.rankLatency(rank);
    }

    public long runTime()
    {
        return (end - start) / 1000000;
    }

    public final long endNanos()
    {
        return end;
    }

    public long startNanos()
    {
        return start;
    }

    public static enum TimingParameter
    {
        OPRATE, ROWRATE, ADJROWRATE, PARTITIONRATE, MEANLATENCY, MAXLATENCY, MEDIANLATENCY, RANKLATENCY,
        ERRORCOUNT, PARTITIONCOUNT
    }

    String getStringValue(TimingParameter value)
    {
        return getStringValue(value, Float.NaN);
    }

    String getStringValue(TimingParameter value, float rank)
    {
        switch (value)
        {
            case OPRATE:         return String.format("%.0f", opRate());
            case ROWRATE:        return String.format("%.0f", rowRate());
            case ADJROWRATE:     return String.format("%.0f", adjustedRowRate());
            case PARTITIONRATE:  return String.format("%.0f", partitionRate());
            case MEANLATENCY:    return String.format("%.1f", meanLatency());
            case MAXLATENCY:     return String.format("%.1f", maxLatency());
            case MEDIANLATENCY:  return String.format("%.1f", medianLatency());
            case RANKLATENCY:    return String.format("%.1f", rankLatency(rank));
            case ERRORCOUNT:     return String.format("%d", errorCount);
            case PARTITIONCOUNT: return String.format("%d", partitionCount);
            default:             throw new IllegalStateException();
        }
    }
 }

