/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed 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.
 */

package org.drrickorang.loopback;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Iterator;

/**
 * Maintains and returns pairs of callback timestamps (in milliseconds since beginning of test) and
 * lengths (milliseconds between a callback and the previous callback).
 */
public class BufferCallbackTimes implements Iterable<BufferCallbackTimes.BufferCallback>, Parcelable {
    private final int[] mTimeStamps;
    private final short[] mCallbackDurations;
    private final short mExpectedBufferPeriod;
    private boolean mExceededCapacity;
    private int mIndex;

    public BufferCallbackTimes(int maxRecords, int expectedBufferPeriod) {
        mIndex = 0;
        mTimeStamps = new int[maxRecords];
        mCallbackDurations = new short[maxRecords];
        mExceededCapacity = false;
        mExpectedBufferPeriod = (short) expectedBufferPeriod;
    }

    /**
     * Instantiates an iterable object with already recorded callback times and lengths
     * used for callbacks recorded by native sles callback functions.
     *
     * exceededCapacity should be set to true only when there were late callbacks observed but
     * unable to be recorded because allocated arrays were already at capacity
     */
    public BufferCallbackTimes(int[] timeStamps, short[] callbackDurations,
                               boolean exceededCapacity, short expectedBufferPeriod) {
        mTimeStamps = timeStamps;
        mCallbackDurations = callbackDurations;
        mExceededCapacity = exceededCapacity;
        mIndex = mTimeStamps.length;
        mExpectedBufferPeriod = expectedBufferPeriod;
    }

    /** Record the length of a late/early callback and the time it occurred. Used by Java Thread. */
    public void recordCallbackTime(int timeStamp, short callbackLength) {
        if (!mExceededCapacity && callbackLength != mExpectedBufferPeriod
                && callbackLength != mExpectedBufferPeriod + 1) {
            //only marked as exceeded if attempting to record a late callback after arrays full
            if (mIndex == mTimeStamps.length) {
                mExceededCapacity = true;
                return;
            }
            mTimeStamps[mIndex] = timeStamp;
            mCallbackDurations[mIndex] = callbackLength;
            mIndex++;
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (BufferCallback callback : this) {
            sb.append(callback.timeStamp);
            sb.append(",");
            sb.append(callback.callbackDuration);
            sb.append("\n");
        }
        return sb.toString();
    }

    // True only if arrays are full and recording more late or early callbacks is attempted.
    public boolean isCapacityExceeded() {
        return mExceededCapacity;
    }

    public int getNumLateOrEarlyCallbacks() {
        return mIndex;
    }

    public short getExpectedBufferPeriod() {
        return mExpectedBufferPeriod;
    }

    @Override
    public Iterator<BufferCallback> iterator() {
        return new Iterator<BufferCallback>() {
            int mIteratorIndex = 0;

            @Override
            public boolean hasNext() {
                return mIteratorIndex < mIndex;
            }

            @Override
            public BufferCallback next() {
                return new BufferCallback(mTimeStamps[mIteratorIndex],
                        mCallbackDurations[mIteratorIndex++]);
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Buffer Time Stamps are Immutable");
            }
        };
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Bundle out = new Bundle();
        out.putIntArray("mTimeStamps", mTimeStamps);
        out.putShortArray("mCallbackDurations", mCallbackDurations);
        out.putShort("mExpectedBufferPeriod", mExpectedBufferPeriod);
        out.putBoolean("mExceededCapacity", mExceededCapacity);
        out.putInt("mIndex", mIndex);
        dest.writeBundle(out);
    }

    private BufferCallbackTimes(Parcel source) {
        Bundle in = source.readBundle(getClass().getClassLoader());
        mTimeStamps = in.getIntArray("mTimeStamps");
        mCallbackDurations = in.getShortArray("mCallbackDurations");
        mExpectedBufferPeriod = in.getShort("mExpectedBufferPeriod");
        mExceededCapacity = in.getBoolean("mExceededCapacity");
        mIndex = in.getInt("mIndex");
    }

    public static final Parcelable.Creator<BufferCallbackTimes> CREATOR
             = new Parcelable.Creator<BufferCallbackTimes>() {
         public BufferCallbackTimes createFromParcel(Parcel in) {
             return new BufferCallbackTimes(in);
         }

         public BufferCallbackTimes[] newArray(int size) {
             return new BufferCallbackTimes[size];
         }
     };

    /** Wrapper for iteration over timestamp and length pairs */
    public class BufferCallback {
        public final int timeStamp;
        public final short callbackDuration;

        BufferCallback(final int ts, final short cd) {
            timeStamp = ts;
            callbackDuration = cd;
        }
    }
}
