package org.apache.jcs.admin;

/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * 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.
 */

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import org.apache.jcs.engine.behavior.ICacheElement;
import org.apache.jcs.engine.behavior.IElementAttributes;
import org.apache.jcs.engine.control.CompositeCache;
import org.apache.jcs.engine.control.CompositeCacheManager;
import org.apache.jcs.engine.memory.MemoryCache;

/**
 * A servlet which provides HTTP access to JCS. Allows a summary of regions
 * to be viewed, and removeAll to be run on individual regions or all regions.
 * Also provides the ability to remove items (any number of key arguments can
 * be provided with action 'remove'). Should be initialized with a properties
 * file that provides at least a classpath resource loader.
 *
 */
public class JCSAdminBean
{

  private CompositeCacheManager cacheHub = CompositeCacheManager.getInstance();

  /**
   * Builds up info about each element in a region.
   * 
   * @param cacheName
   * @return
   * @throws Exception
   */
  public LinkedList buildElementInfo( String cacheName ) throws Exception
  {
    CompositeCache cache =
        cacheHub.getCache( cacheName );

    Object[] keys = cache.getMemoryCache().getKeyArray();

    // Attempt to sort keys according to their natural ordering. If that
    // fails, get the key array again and continue unsorted.

    try
    {
      Arrays.sort( keys );
    }
    catch ( Exception e )
    {
      keys = cache.getMemoryCache().getKeyArray();
    }

    LinkedList records = new LinkedList();

    ICacheElement element;
    IElementAttributes attributes;
    CacheElementInfo elementInfo;

    DateFormat format = DateFormat.getDateTimeInstance( DateFormat.SHORT,
        DateFormat.SHORT );

    long now = System.currentTimeMillis();

    for ( int i = 0; i < keys.length; i++ )
    {
      element =
          cache.getMemoryCache().getQuiet( ( Serializable ) keys[i] );

      attributes = element.getElementAttributes();

      elementInfo = new CacheElementInfo();

      elementInfo.key = String.valueOf( keys[i] );
      elementInfo.eternal = attributes.getIsEternal();
      elementInfo.maxLifeSeconds = attributes.getMaxLifeSeconds();

      elementInfo.createTime =
          format.format( new Date( attributes.getCreateTime() ) );

      elementInfo.expiresInSeconds =
          ( now - attributes.getCreateTime()
            - ( attributes.getMaxLifeSeconds() * 1000 ) ) / -1000;

      records.add( elementInfo );
    }

    return records;
  }

  /**
   * Builds up data on every region.
   * @TODO we need a most light weight method that does not count
   * bytes.  The byte counting can really swamp a server.
   * 
   * @return list of CacheRegionInfo objects
   * @throws Exception
   */
  public LinkedList buildCacheInfo() throws Exception
  {
    String[] cacheNames = cacheHub.getCacheNames();

    Arrays.sort( cacheNames );

    LinkedList cacheInfo = new LinkedList();

    CacheRegionInfo regionInfo;
    CompositeCache cache;

    for ( int i = 0; i < cacheNames.length; i++ )
    {
      cache = cacheHub.getCache( cacheNames[i] );

      regionInfo = new CacheRegionInfo();

      regionInfo.cache = cache;
      regionInfo.byteCount = getByteCount( cache );

      cacheInfo.add( regionInfo );
    }

    return cacheInfo;
  }

  /**
   * Tries to estimate how much data is in a region.  
   * This is expensive.
   * If there are any non serializable objects in the region,
   * the count will stop when it encouters the first one.
   * 
   * @param cache
   * @return
   * @throws Exception
   */
  public int getByteCount( CompositeCache cache ) throws Exception
  {
    MemoryCache memCache = cache.getMemoryCache();

    Iterator iter = memCache.getIterator();

    CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
    ObjectOutputStream out = new ObjectOutputStream( counter );

    // non serializable objects will cause problems here
    try
    {
      while ( iter.hasNext() )
      {
        ICacheElement ce = ( ICacheElement )
            ( ( Map.Entry ) iter.next() ).getValue();

        out.writeObject( ce.getVal() );
      }
    }
    catch ( Exception e )
    {
      //log later
    }

    // 4 bytes lost for the serialization header

    return counter.getCount() - 4;
  }

  /**
   * Clears all regions in the cache.
   * 
   * @throws IOException
   */
  public void clearAllRegions() throws IOException
  {
    String[] names = cacheHub.getCacheNames();

    for ( int i = 0; i < names.length; i++ )
    {
      cacheHub.getCache( names[i] ).removeAll();
    }
  }

  /**
   * Clears a particular cache region.
   * 
   * @param cacheName
   * @throws IOException
   */
  public void clearRegion( String cacheName ) throws IOException
  {
    cacheHub.getCache( cacheName ).removeAll();
  }

  /**
   * Removes a particular item from a particular region.
   * 
   * @param cacheName
   * @param key
   * @throws IOException
   */
  public void removeItem( String cacheName, String key ) throws IOException
  {
    cacheHub.getCache( cacheName ).remove( key );
  }

}
