/*
 * Copyright (C) 2015 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 com.android.tv.util;

import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.LongSparseArray;
import java.util.Collections;
import java.util.Set;

/**
 * Uses a {@link LongSparseArray} to hold sets of {@code T}.
 *
 * <p>This has the same memory and performance trade offs listed in {@link LongSparseArray}.
 */
public class MultiLongSparseArray<T> {
    @VisibleForTesting static final int DEFAULT_MAX_EMPTIES_KEPT = 4;
    private final LongSparseArray<Set<T>> mSparseArray;
    private final Set<T>[] mEmptySets;
    private int mEmptyIndex = -1;

    public MultiLongSparseArray() {
        mSparseArray = new LongSparseArray<>();
        mEmptySets = new Set[DEFAULT_MAX_EMPTIES_KEPT];
    }

    public MultiLongSparseArray(int initialCapacity, int emptyCacheSize) {
        mSparseArray = new LongSparseArray<>(initialCapacity);
        mEmptySets = new Set[emptyCacheSize];
    }

    /**
     * Adds a mapping from the specified key to the specified value, replacing the previous mapping
     * from the specified key if there was one.
     */
    public void put(long key, T value) {
        Set<T> values = mSparseArray.get(key);
        if (values == null) {
            values = getEmptySet();
            mSparseArray.put(key, values);
        }
        values.add(value);
    }

    /** Removes the value at the specified index. */
    public void remove(long key, T value) {
        Set<T> values = mSparseArray.get(key);
        if (values != null) {
            values.remove(value);
            if (values.isEmpty()) {
                mSparseArray.remove(key);
                cacheEmptySet(values);
            }
        }
    }

    /**
     * Gets the set of Objects mapped from the specified key, or an empty set if no such mapping has
     * been made.
     */
    public Iterable<T> get(long key) {
        Set<T> values = mSparseArray.get(key);
        return values == null ? Collections.EMPTY_SET : values;
    }

    /** Clears cached empty sets. */
    public void clearEmptyCache() {
        while (mEmptyIndex >= 0) {
            mEmptySets[mEmptyIndex--] = null;
        }
    }

    @VisibleForTesting
    int getEmptyCacheSize() {
        return mEmptyIndex + 1;
    }

    private void cacheEmptySet(Set<T> emptySet) {
        if (mEmptyIndex < DEFAULT_MAX_EMPTIES_KEPT - 1) {
            mEmptySets[++mEmptyIndex] = emptySet;
        }
    }

    private Set<T> getEmptySet() {
        if (mEmptyIndex < 0) {
            return new ArraySet<>();
        }
        Set<T> emptySet = mEmptySets[mEmptyIndex];
        mEmptySets[mEmptyIndex--] = null;
        return emptySet;
    }

    @Override
    public String toString() {
        return mSparseArray.toString() + "(emptyCacheSize=" + getEmptyCacheSize() + ")";
    }
}
