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.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

// relatively simple timing class for getting a uniform sample of latencies, and saving other metrics
// ensures accuracy of timing by having single threaded timers that are check-pointed by the snapping thread,
// which waits for them to report back. They report back the data up to the last event prior to the check-point.
// if the threads are blocked/paused this may mean a period of time longer than the checkpoint elapses, but that all
// metrics calculated over the interval are accurate
public class Timing
{
    // concurrency: this should be ok as the consumers are created serially by StressAction.run / warmup
    // Probably the CopyOnWriteArrayList could be changed to an ordinary list as well.
    private final Map<String, List<Timer>> timers = new TreeMap<>();
    private volatile TimingIntervals history;
    private boolean done;
    private boolean isFixed;

    public Timing(boolean isFixed)
    {
        this.isFixed = isFixed;
    }

    // TIMING

    public static class TimingResult<E>
    {
        public final E extra;
        public final TimingIntervals intervals;
        public TimingResult(E extra, TimingIntervals intervals)
        {
            this.extra = extra;
            this.intervals = intervals;
        }
    }

    public <E> TimingResult<E> snap(Callable<E> call) throws InterruptedException
    {
        // Count up total # of timers
        int timerCount = 0;
        for (List<Timer> timersForOperation : timers.values())
        {
            timerCount += timersForOperation.size();
        }
        final CountDownLatch ready = new CountDownLatch(timerCount);

        // request reports
        for (List <Timer> timersForOperation : timers.values())
        {
            for(Timer timer : timersForOperation)
            {
                timer.requestReport(ready);
            }
        }

        E extra;
        try
        {
            extra = call.call();
        }
        catch (Exception e)
        {
            if (e instanceof InterruptedException)
                throw (InterruptedException) e;
            throw new RuntimeException(e);
        }

        // TODO fail gracefully after timeout if a thread is stuck
        if (!ready.await(5L, TimeUnit.MINUTES))
        {
            throw new RuntimeException("Timed out waiting for a timer thread - seems one got stuck. Check GC/Heap size");
        }

        boolean done = true;

        // reports have been filled in by timer threadCount, so merge
        Map<String, TimingInterval> intervals = new TreeMap<>();
        for (Map.Entry<String, List<Timer>> entry : timers.entrySet())
        {
            List<TimingInterval> operationIntervals = new ArrayList<>();
            for (Timer timer : entry.getValue())
            {
                operationIntervals.add(timer.report);
                done &= !timer.running();
            }

            intervals.put(entry.getKey(), TimingInterval.merge(operationIntervals,
                                                              history.get(entry.getKey()).endNanos()));
        }

        TimingIntervals result = new TimingIntervals(intervals);
        this.done = done;
        history = history.merge(result, history.startNanos());
        return new TimingResult<>(extra, result);
    }

    // build a new timer and add it to the set of running timers.
    public Timer newTimer(String opType)
    {
        final Timer timer = new Timer(isFixed);

        if (!timers.containsKey(opType))
            timers.put(opType, new ArrayList<Timer>());

        timers.get(opType).add(timer);
        return timer;
    }

    public void start()
    {
        history = new TimingIntervals(timers.keySet());
    }

    public boolean done()
    {
        return done;
    }

    public TimingIntervals getHistory()
    {
        return history;
    }
}
