key0-96/
key0-96/doc/key/
key0-96/doc/key/credits/
key0-96/doc/key/developers/
key0-96/doc/key/developers/resources/
key0-96/setup/caves/
key0-96/setup/help/
key0-96/setup/ruins/
key0-96/src/
key0-96/src/commands/
key0-96/src/events/
key0-96/src/hack/
key0-96/src/sql/
key0-96/src/swing/
key0-96/src/talker/forest/
key0-96/src/talker/objects/
key0-96/src/terminals/
/*
**               j###t  ########## ####   ####
**              j###t   ########## ####   ####
**             j###T               "###L J###"
**          ######P'    ##########  #########
**          ######k,    ##########   T######T
**          ####~###L   ####
**          #### q###L  ##########   .#####
**          ####  \###L ##########   #####"
**
**  $Id: ViewLog.java,v 1.1 1997/07/20 16:24:05 subtle Exp subtle $
**
**  Class History
**  
**  Date        Name         Description
**  ---------|------------|-----------------------------------------------
**  19Jul97     subtle      created this command
**
*/

package key.commands;

import key.*;

import java.io.*;
import java.util.StringTokenizer;
import java.util.Hashtable;

public class ViewLog extends Command
{
	private static final long serialVersionUID = 4263891712481759116L;
	
	public static final AtomicElement[] ELEMENTS =
	{
			//  if this field is specified, it is used as the log file.
			//  if this field ends with '/', what the player types as
			//  an argument is appended to this name to get the path
		AtomicElement.construct( ViewLog.class, String.class, "logName",
			AtomicElement.PUBLIC_FIELD,
			"the name of the log file" ),
	};
	
	public static final AtomicStructure STRUCTURE = new AtomicStructure( Command.STRUCTURE, ELEMENTS );
	
	public String logName = "";
	
	public ViewLog()
	{
		setKey( "vlog" );
		usage = "<logname>";
	}
	
	public AtomicStructure getDeclaredStructure()
	{
		return( STRUCTURE );
	}
	
	public void run( Player p, StringTokenizer args, String fullLine, CategoryCommand caller, InteractiveConnection ic, Flags flags ) throws IOException
	{
		String thisLogname;
		
		boolean isnull = (logName == null);
		boolean islengthzero = false;
		boolean directory = false;
		
		if( !isnull )
		{
			islengthzero = (logName.length() == 0);
			
			if( !islengthzero )
				directory = (logName.endsWith( "/" ));
		}
		
		if( isnull || islengthzero || directory )
		{
			if( args.hasMoreTokens() )
			{
				String enteredName = args.nextToken();
				
				if( directory )
					thisLogname = logName + enteredName;
				else
					thisLogname = enteredName;
			}
			else
			{
				usage( ic );
				return;
			}
		}
		else
			thisLogname = logName;
		
		try
		{
			File logsBasePath = Key.instance().getLogsBasePath();
			File logFile = new File( logsBasePath, thisLogname );
			
			if( !logFile.exists() || !logFile.canRead() )
			{
				ic.sendError( "The log file '" + thisLogname + "' does not exist or is not readable." );
				return;
			}
			else
			{
					//  if this is a directory, check that the player
					//  hasn't done something clever (ie, ".." or "/") to get
					//  out of it.
				if( directory )
				{
					File basePath = new File( logsBasePath, logName );
					String lfc = logFile.getCanonicalPath();
					
						//  check to see if this is a valid path
					if( !lfc.startsWith( basePath.getCanonicalPath() ) )
					{
							//  this is not okay
						ic.sendError( "This is not a valid log file name." );
						return;
					}
				}
			}
			
			FileReader fr = Log.viewLog( thisLogname );
			BufferedReader br = new BufferedReader( fr );

				//  META:  this is temporary.  I want to eventually
				//  be able to reverse the lines and display some of them
				//  in reverse order, but this is way into the future.  It'd
				//  be nice if the pager was retro-active, too - allowing me
				//  to pump in a page of data, and have no more requested until
				//  they actually asked for more to be displayed.
			
			String l = br.readLine();
			StringBuffer sb = new StringBuffer();
			
			while( l != null )
			{
				sb.append( l );
				sb.append( '\n' );
				l = br.readLine();
			}
			
			ic.send( new TextParagraph( TextParagraph.LEFT, sb.toString() ) );
			
				//  make it easier to garbage collect all this quickly
			sb.setLength( 0 );
			sb = null;
		}
		catch( IOException e )
		{
			ic.sendFailure( "An error occurred trying to read the '" + thisLogname + "' log file" );
		}
	}
	
	public void usage( InteractiveConnection ic )
	{
		super.usage( ic );
		ic.send( "\nThe following logs are available to be viewed:" );
		File logsBasePath = Key.instance().getLogsBasePath();
		File path;
		
		if( logName == null || logName.length() == 0 )
			path = logsBasePath;
		else
			path = new File( logsBasePath, logName );
		
		String[] li = path.list();
		ic.send( Grammar.commaSeperate( li ) );
	}
}