/*
 * 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.uima.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;

import org.apache.uima.UIMAFramework;
import org.apache.uima.analysis_engine.AnalysisEngine;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.impl.CASImpl;
import org.apache.uima.collection.CasConsumerDescription;
import org.apache.uima.collection.CollectionReaderDescription;
import org.apache.uima.resource.CasDefinition;
import org.apache.uima.resource.CasManager;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.ProcessingResourceMetaData;

/**
 * This class represents a simple pool of {@link CAS} instances. This is useful for multithreaded
 * applications, where there is a need for multiple CASes to be processed simultaneously. Because
 * CAS creation is expensive, it is a good idea to create a pool of reusable CAS instances at
 * initialization time, rather than creating a new CAS each time one is needed.
 * <p>
 * Clients check-out CAS instances from the pool using the {@link #getCas()} method and check-in CAS
 * instances using the {@link #releaseCas(CAS)} method.
 * 
 * 
 * 
 */
public class CasPool {

  /**
   * resource bundle for log messages
   */
  private static final String LOG_RESOURCE_BUNDLE = "org.apache.uima.impl.log_messages";

  /**
   * current class
   */
  private static final Class CLASS_NAME = CasPool.class;

  private Vector mAllInstances = new Vector();

  private Vector mFreeInstances = new Vector();

  private int mNumInstances;

  /**
   * Creates a new CasPool
   * 
   * @param aNumInstances
   *          the number of CAS instances in the pool
   * @param aComponentDescriptionsOrMetaData
   *          a collection of {@link AnalysisEngineDescription},
   *          {@link CollectionReaderDescription}, {@link CasConsumerDescription}, or
   *          {@link ProcessingResourceMetaData} objects.
   * @param aPerformanceTuningSettings
   *          Properties object containing framework performance tuning settings using key names
   *          defined on {@link UIMAFramework} interface
   * @param aResourceManager
   *          the resource manager to use to resolve import declarations within the metadata
   * 
   * @throws ResourceInitializationException
   *           if the CAS instances could not be created
   */
  public CasPool(int aNumInstances, Collection aComponentDescriptionsOrMetaData,
          Properties aPerformanceTuningSettings, ResourceManager aResourceManager)
          throws ResourceInitializationException {
    mNumInstances = aNumInstances;

    fillPool(aComponentDescriptionsOrMetaData, aPerformanceTuningSettings, aResourceManager);
  }

  /**
   * Creates a new CasPool
   * 
   * @param aNumInstances
   *          the number of CAS instances in the pool
   * @param aAnalysisEngine
   *          the analysis engine that will create the CAS instances and which will later be used to
   *          process them
   * 
   * @throws ResourceInitializationException
   *           if the CAS instances could not be created
   */
  public CasPool(int aNumInstances, AnalysisEngine aAnalysisEngine)
          throws ResourceInitializationException {
    mNumInstances = aNumInstances;
    ArrayList mdList = new ArrayList();
    mdList.add(aAnalysisEngine.getMetaData());
    fillPool(mdList, aAnalysisEngine.getPerformanceTuningSettings(), aAnalysisEngine
            .getResourceManager());
  }

  /**
   * Creates a new CasPool
   * 
   * @param aNumInstances
   *          the number of CAS instances in the pool
   * @param aMetaData
   *          metadata that includes the type system for the CAS
   * 
   * @throws ResourceInitializationException
   *           if the CAS instances could not be created
   */
  public CasPool(int aNumInstances, ProcessingResourceMetaData aMetaData)
          throws ResourceInitializationException {
    mNumInstances = aNumInstances;
    ArrayList mdList = new ArrayList();
    mdList.add(aMetaData);
    fillPool(mdList, null, null);
  }

  /**
   * Creates a new CasPool
   * 
   * @param aNumInstances
   *          the number of CAS instances in the pool
   * @param aMetaData
   *          metadata that includes the type system for the CAS
   * 
   * @throws ResourceInitializationException
   *           if the CAS instances could not be created
   */
  public CasPool(int aNumInstances, ProcessingResourceMetaData aMetaData,
          ResourceManager aResourceManager) throws ResourceInitializationException {
    mNumInstances = aNumInstances;

    ArrayList mdList = new ArrayList();
    mdList.add(aMetaData);
    fillPool(mdList, null, aResourceManager);
  }

  /**
   * Creates a new CasPool.
   * TODO: do we need this method AND the one that takes a CasManager?
   * 
   * @param aNumInstances
   *          the number of CAS instances in the pool
   * @param aCasDefinition
   *          the Cas definition, which includes the type system, type priorities, and indexes for
   *          the CASes in the pool.
   * @param aPerformanceTuningSettings
   *          Properties object containing framework performance tuning settings using key names
   *          defined on {@link UIMAFramework} interface
   */
  public CasPool(int aNumInstances, CasDefinition aCasDefinition,
          Properties aPerformanceTuningSettings) throws ResourceInitializationException {
    mNumInstances = aNumInstances;
    fillPool(aCasDefinition, aPerformanceTuningSettings);
  }

  /**
   * Creates a new CasPool
   * 
   * @param aNumInstances
   *          the number of CAS instances in the pool
   * @param aCasManager
   *          CAS Manager that will be used to create the CAS.  The CAS Manager
   *          holds the CAS Definition.  Also all CASes created from the same
   *          CAS Manager will share identical TypeSystem objects.
   * @param aPerformanceTuningSettings
   *          Properties object containing framework performance tuning settings using key names
   *          defined on {@link UIMAFramework} interface
   */
  public CasPool(int aNumInstances, CasManager aCasManager,
          Properties aPerformanceTuningSettings) throws ResourceInitializationException {
    mNumInstances = aNumInstances;
    fillPool(aCasManager, aPerformanceTuningSettings);
  }
  
  /**
   * Checks out a CAS from the pool.
   * 
   * @return a CAS instance. Returns <code>null</code> if none are available (in which case the
   *         client may {@link Object#wait()} on this object in order to be notified when an
   *         instance becomes available).
   */
  public synchronized CAS getCas() {
    if (!mFreeInstances.isEmpty()) {
      return (CAS) mFreeInstances.remove(0);
    } else {
      // no instances available
      return null;
    }
  }

  /**
   * Checks in a CAS to the pool. This automatically calls the {@link CAS#reset()} method, to ensure
   * that when the CAS is later retrieved from the pool it will be ready to use. Also notifies other
   * Threads that may be waiting for an instance to become available.
   * 
   * @param aCas
   *          the Cas to release
   */
  public synchronized void releaseCas(CAS aCas) {
    // note the pool stores references to the InitialView of each CAS
    CAS cas = aCas.getView(CAS.NAME_DEFAULT_SOFA);

    // make sure this CAS actually belongs to this pool and is checked out
    if (!mAllInstances.contains(cas) || mFreeInstances.contains(cas)) {
      UIMAFramework.getLogger(CLASS_NAME).logrb(Level.WARNING, CLASS_NAME.getName(), "releaseCas",
              LOG_RESOURCE_BUNDLE, "UIMA_return_cas_to_pool__WARNING");
    } else {
      // reset CAS
      cas.reset();

      // restore the ClassLoader and unlock the CAS, since release() can be called 
      // from within a CAS Multiplier.
      ((CASImpl)cas).restoreClassLoaderUnlockCas();  
      
      // Add the CAS to the end of the free instances List
      mFreeInstances.add(cas);
    }

    // Notify any threads waiting on this object
    notifyAll();
  }

  /**
   * Checks out a CAS from the pool. If none is currently available, wait for the specified amount
   * of time for one to be checked in.
   * 
   * @param aTimeout
   *          the time to wait in milliseconds. A value of &lt;=0 will wait forever.
   * 
   * @return a CAS instance. Returns <code>null</code> if none are available within the specified
   *         timeout period.
   */
  public synchronized CAS getCas(long aTimeout) {
    long startTime = new Date().getTime();
    CAS cas;
    while ((cas = getCas()) == null) {
      try {
        wait(aTimeout);
      } catch (InterruptedException e) {
      }
      if (aTimeout > 0 && (new Date().getTime() - startTime) >= aTimeout) {
        // Timeout has expired
        return null;
      }
    }
    return cas;
  }

  /**
   * Gets the size of this pool (the total number of CAS instances that it can hold).
   * 
   * @return the size of this pool
   */
  public int getSize() {
    return mNumInstances;
  }
  
  /**
   * Gets the number of CASes currently available in this pool.
   * @return the numberof available CASes 
   */
  public int getNumAvailable() {
    return getFreeInstances().size();
  }  

  /**
   * @param componentDescriptionsOrMetaData
   * @param performanceTuningSettings
   * @param resourceManager
   */
  private void fillPool(Collection mdList, Properties performanceTuningSettings,
          ResourceManager resourceManager) throws ResourceInitializationException {
    CasDefinition casDef = new CasDefinition(mdList, resourceManager);
    fillPool(casDef, performanceTuningSettings);
  }

  private void fillPool(CasDefinition casDef, Properties performanceTuningSettings)
          throws ResourceInitializationException {
    // create first CAS from metadata
    CAS c0 = CasCreationUtils.createCas(casDef, performanceTuningSettings);
    // set owner so cas.release() can return it to the pool
    ((CASImpl) c0).setOwner(casDef.getCasManager());
    mAllInstances.add(c0);
    mFreeInstances.add(c0);
    // create additional CASes that share same type system
    for (int i = 1; i < mNumInstances; i++) {
      CAS c = CasCreationUtils.createCas(casDef, performanceTuningSettings, c0.getTypeSystem());
      ((CASImpl) c).setOwner(casDef.getCasManager());
      mAllInstances.add(c);
      mFreeInstances.add(c);
    }
  }

  private void fillPool(CasManager casManager, Properties performanceTuningSettings)
          throws ResourceInitializationException {
    // create additional CASes that share same type system
    for (int i = 0; i < mNumInstances; i++) {
      CAS c = casManager.createNewCas(performanceTuningSettings);
      ((CASImpl) c).setOwner(casManager);
      mAllInstances.add(c);
      mFreeInstances.add(c);
    }
  }  
  
  protected Vector getAllInstances() {
    return mAllInstances;
  }

  protected Vector getFreeInstances() {
    return mFreeInstances;
  }
}
