/*
 *  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.
 */
package org.apache.myfaces.buildtools.maven2.plugin.javascript.uixtools;

import java.util.List;

/**
 * Implements a first-in-first-out (FIFO) queue. Typically, one thread will add
 * elements to this queue, and another will remove elements from this queue.
 * This class is thread safe.
 * @version $Name:  $ ($Revision$) $Date$
 */
public class Queue
{
  /**
   * @param size the maximum size of this queue
   */
  public Queue(int size)
  {
    if (size<=0)
      throw new IllegalArgumentException("size is nonpositive:"+size);
    _buf = new Object[size];
  }

  /**
   * @return the number of elements in this queue. This will never be larger
   * than the {@link #Queue(int) maximum size} of this queue.
   */
  public final synchronized int size()
  {
    return _size;
  }

  /**
   * @return true if the queue has been closed.
   * @see #close()
   */
  public final synchronized boolean isClosed()
  {
    return _closed;
  }

  /**
   * closes this queue. Any consequent {@link #add(Object)} method calls will
   * fail.  All {@link #get()} operations will succeed until the queue is
   * empty. This method may be called multiple times.
   * @see #isClosed()
   */
  public synchronized void close()
  {
    _closed = true;
    notifyAll();
  }

  /**
   * @return true if the queue is full and a call to {@link #add(Object)}
   * would block.
   */
  public final boolean isFull()
  {
    return (size() == _buf.length);
  }

  /**
   * @return true if the queue is empty and a call to {@link #get()}
   * would block.
   */
  public final boolean isEmpty()
  {
    return (size() == 0);
  }

  /**
   * This method blocks until space is available in this queue.
   * @param obj the Object to add to the end of this queue. null is permitted.
   * @exception InterruptedException if the current thread is interrupted.
   * @exception IllegalStateException if queue is closed.
   * @see #close()
   * @see #remove()
   */
  public synchronized void add(Object obj)
    throws InterruptedException, IllegalStateException
  {
    for(;isFull() && (!isClosed());)
    {
      //ystem.out.println("waiting to add. size");
      wait();
    }
    //ystem.out.println("adding. size:"+size());

    _checkIsClosed();

    _buf[_head] = obj;
    _head = _incIndex(_head);
    _size++;
    // yes, we are waking up all threads, including those that are
    // waiting to do an add. This may be inefficient.
    // note that we must do notifyAll() and not notify()
    notifyAll();
  }

  /**
   * This method blocks until some element is added to this queue, or the queue
   * is closed.
   * @return removes and returns the Object at the front of this queue.
   * null may be returned if null was added using {@link #add(Object)}
   * @exception InterruptedException if the current thread is interrupted.
   * @exception IllegalStateException if queue is closed.
   * @see #close()
   * @see #add(Object)
   * @see #remove(LIst,int)
   */
  public synchronized Object remove()
    throws InterruptedException, IllegalStateException
  {
    for(;isEmpty();)
    {
      _checkIsClosed();
      wait();
    }

    Object res = _buf[_tail];
    _buf[_tail] = null; // allow garbage collect
    _tail = _incIndex(_tail);
    _size--;

    // yes, we are waking up all threads, including those that are
    // waiting to do a remove. This may be inefficient.
    // note that we must do notifyAll() and not notify()
    notifyAll();
    return res;
  }

  /**
   * Removes multiple elements. This method will block until there is something
   * to remove.
   * @param collector all the elements removed from this queue are added to
   * the end of this List.
   * @param count the maximum number of elements to remove. If this is zero,
   * then it defaults to the maximum size of this queue.
   * @return the number of elements actually removed.
   * @see #remove()
   */
  public synchronized int remove(List collector, int count)
    throws InterruptedException, IllegalStateException
  {
    collector.add(remove());

    int sz = size()+1;
    if ((count == 0) || (count > sz))
      count = sz;
    else if (count < 0)
      throw new IllegalArgumentException("count is negative");

    int read = 1;
    try
    {
      for(;read < count; read++)
      {
        collector.add(remove());
      }
    }
    catch(IllegalStateException e)
    {
      // this should not happen unless the user has subclassed remove() and
      // done something weird
    }
    catch(InterruptedException e)
    {
      // this should not happen unless the user has subclassed remove() and
      // done something weird

      // mark this thread as interrupted, so that it doesn't block again.
      Thread.currentThread().interrupt();
    }
    return read;
  }

  private int _incIndex(int index)
  {
    index++;
    return (index < _buf.length) ? index : 0;
  }

  private void _checkIsClosed()
  {
    if (isClosed())
      throw new IllegalStateException("Queue has been closed");
  }

  private final Object[] _buf;
  private boolean _closed = false;
  private int _size = 0, _head = 0, _tail = 0;
}