/*
 * Copyright 2011 Google Inc.
 * 
 * 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.google.gwt.user.server.rpc.impl;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;

/**
 * MultiMap with stack semantics for the values.
 * 
 * Initial insertion of a given key results in a new stack containing the value.
 * Subsequent puts for the same key add the value to the stack. Removing a key
 * removes its value from the stack.
 * 
 * @param <K> The key to use in the map
 * @param <V> The value to put in the deque
 */
public class DequeMap<K, V> {
  /**
   * The default initial capacity for the Deque objects.
   */
  static final int DEFAULT_INITIAL_DEQUE_CAPACITY = 3;

  /**
   * The default initial capacity for the Deque objects.
   */
  static final int DEFAULT_INITIAL_MAP_CAPACITY = 3;

  /**
   * The initial capacity for the Deque objects.
   */
  int dequeCapacity = DEFAULT_INITIAL_DEQUE_CAPACITY;

  /**
   * The map used to hold data.
   * 
   * Note that we do not extend map because we require control over the
   * addition and removal of elements from the map.
   */
  HashMap<K, Deque<V>> map = null;

  /**
   * Constructs an empty <tt>DequeMap</tt> with the default initial capacities
   * (3 and 3) and the default map load factor (0.75).
   */
  public DequeMap() {
    this(DEFAULT_INITIAL_MAP_CAPACITY, DEFAULT_INITIAL_DEQUE_CAPACITY);
  }

  /**
   * Constructs an empty <tt>DequeMap</tt> with the specified initial capacities
   * and the default map load factor (0.75).
   * 
   * @param initialMapCapacity the initial map capacity.
   * @param initialDequeCapacity the initial deque capacity.
   * @throws IllegalArgumentException if the initial capacity is negative.
   */
  public DequeMap(int initialMapCapacity, int initialDequeCapacity) {
    map = new HashMap<K, Deque<V>>(initialMapCapacity);
    dequeCapacity = initialDequeCapacity;
  }

  /**
   * Add a value for a key to the map.
   * 
   * If the key already exists, the value is added to the head of the queue at
   * that key. Otherwise, a new queue containing the value is created and
   * inserted into the map at the key.
   * 
   * @param key key with which the specified value is to be associated
   * @param value the value to push for the key
   */
  public void add(K key, V value) {
    Deque<V> deque = map.get(key);
    if (deque == null) {
      deque = new ArrayDeque<V>(dequeCapacity);
      deque.addFirst(value);
      map.put(key, deque);
    } else {
      deque.addFirst(value);
    }
  }

  /**
   * Get the most recent value for a key.
   * 
   * @param key key to get
   * @return the value at the head of the stack for the key, or null if the key
   *         is unknown.
   */
  public V get(K key) {
    Deque<V> deque = map.get(key);
    if (deque == null) {
      return null;
    }
    return deque.peekFirst();
  }

  /**
   * Remove the most recent value for a key.
   * 
   * @param key key to get
   * @return the value at the head of the stack for the key, or null if the key
   *         is unknown.
   */
  public V remove(K key) {
    Deque<V> deque = map.get(key);
    if (deque == null) {
      return null;
    }
    return deque.pollFirst();
  }
}
