/*
 * Copyright (C) 2018 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 android.app.usage;

import java.util.ArrayList;

/**
 * A container to keep {@link UsageEvents.Event usage events} in non-descending order of their
 * {@link UsageEvents.Event#mTimeStamp timestamps}.
 *
 * @hide
 */
public class EventList {

    private final ArrayList<UsageEvents.Event> mEvents;

    /**
     * Create a new event list with default capacity
     */
    public EventList() {
        mEvents = new ArrayList<>();
    }

    /**
     * Returns the size of the list
     * @return the number of events in the list
     */
    public int size() {
        return mEvents.size();
    }

    /**
     * Removes all events from the list
     */
    public void clear() {
        mEvents.clear();
    }

    /**
     * Returns the {@link UsageEvents.Event event} at the specified position in this list.
     * @param index the index of the event to return, such that {@code 0 <= index < size()}
     * @return The {@link UsageEvents.Event event} at position {@code index}
     */
    public UsageEvents.Event get(int index) {
        return mEvents.get(index);
    }

    /**
     * Inserts the given {@link UsageEvents.Event event} into the list while keeping the list sorted
     * based on the event {@link UsageEvents.Event#mTimeStamp timestamps}.
     *
     * @param event The event to insert
     */
    public void insert(UsageEvents.Event event) {
        final int size = mEvents.size();
        // fast case: just append if this is the latest event
        if (size == 0 || event.mTimeStamp >= mEvents.get(size - 1).mTimeStamp) {
            mEvents.add(event);
            return;
        }
        // To minimize number of elements being shifted, insert at the first occurrence of the next
        // greatest timestamp in the list.
        final int insertIndex = firstIndexOnOrAfter(event.mTimeStamp + 1);
        mEvents.add(insertIndex, event);
    }

    /**
     * Finds the index of the first event whose timestamp is greater than or equal to the given
     * timestamp.
     *
     * @param timeStamp The timestamp for which to search the list.
     * @return The smallest {@code index} for which {@code (get(index).mTimeStamp >= timeStamp)} is
     * {@code true}, or {@link #size() size} if no such {@code index} exists.
     */
    public int firstIndexOnOrAfter(long timeStamp) {
        final int size = mEvents.size();
        int result = size;
        int lo = 0;
        int hi = size - 1;
        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final long midTimeStamp = mEvents.get(mid).mTimeStamp;
            if (midTimeStamp >= timeStamp) {
                hi = mid - 1;
                result = mid;
            } else {
                lo = mid + 1;
            }
        }
        return result;
    }

    /**
     * Merge the {@link UsageEvents.Event events} in the given {@link EventList list} into this
     * list while keeping the list sorted based on the event {@link
     * UsageEvents.Event#mTimeStamp timestamps}.
     *
     * @param events The event list to merge
     */
    public void merge(EventList events) {
        final int size = events.size();
        for (int i = 0; i < size; i++) {
            insert(events.get(i));
        }
    }
}
