/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */
 
/*
 * $Header: /cvs/glassfish/admin-cli/cli-api/src/java/com/sun/cli/jmx/cmd/CmdMgr.java,v 1.3 2005/12/25 03:45:29 tcfujii Exp $
 * $Revision: 1.3 $
 * $Date: 2005/12/25 03:45:29 $
 */
 
package com.sun.cli.jmx.cmd;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import com.sun.cli.util.stringifier.ArrayStringifier;
import com.sun.cli.util.stringifier.SmartStringifier;
import com.sun.cli.util.LineReaderImpl;
import com.sun.cli.util.ClassUtil;
import com.sun.cli.jmx.cmd.CmdFactoryIniter;

public final class CmdMgr
{
	final CmdEnvImpl			mCmdEnv;
	final CmdFactory			mCmdFactory;
	final CmdRunner				mCmdRunner;
	
		private static void
	dm( Object o )
	{
		System.out.println( SmartStringifier.toString( o ) );
	}
	
		public
	CmdMgr(  )
		throws Exception
	{
		mCmdEnv		= new CmdEnvImpl();
		mCmdFactory	= new CmdFactory( );
		mCmdRunner	= new CmdRunnerImpl( mCmdFactory, mCmdEnv );
		
		mCmdEnv.put( CmdBase.ENV_CMD_RUNNER, mCmdRunner, false);
		mCmdEnv.put( CmdBase.ENV_CMD_FACTORY, mCmdFactory, false);
	}


	
		
	private final static Class [] CMDS =
	{
		GetCmd.class,
		SetCmd.class,
		FindCmd.class,
		InspectCmd.class,
		CreateCmd.class,
		DeleteCmd.class,
		ListenCmd.class,
		InvokeCmd.class,
		CreateAliasCmd.class,
		DeleteAliasCmd.class,
		ResolveAliasCmd.class,
		ListAliasesCmd.class,
		TargetCmd.class,
		ConnectCmd.class,
		HelpCmd.class,
		SourceCmd.class,
		CountCmd.class,
		DomainsCmd.class,
		ConfigureCmd.class,
		SetenvCmd.class,
	};
		
		private void
	initCmds()
		throws Exception
	{
		final CmdFactoryIniter	initer = new CmdFactoryIniter( mCmdFactory, CMDS );
		
		// initialize all non-built-in commands
		final ConfigureCmd.ClassList	list =
				new ConfigureCmd.ClassList( (String)mCmdEnv.get( CmdBase.ENV_COMMANDS ) );
		final java.util.Iterator	iter	= list.iterator();
		while ( iter.hasNext() )
		{
			final String	classname	= (String)iter.next();
			
			initer.addMappings( ClassUtil.getClassFromName( classname ) );
		}
	}
	
		void
	handleSingle( String [] args )
		throws Exception
	{
		// one-off command mode.  Only allowed meta option is a connect string "--connect"
		final String	OPTIONS	= "connect,1";
					
		final ArgHelperImpl	argHelper	= new ArgHelperImpl( Arrays.asList( args ).listIterator(),
								new ArgHelperOptionsInfo( OPTIONS ));
		
		String		lines	= "";
		
		final String connectString		= argHelper.getString( "connect", null );
		if ( connectString != null )
		{
			CmdReader.processLine( "connect " + connectString, mCmdRunner );
		}
		
		// now execute the remainder of the line
		final String []	remainder	= argHelper.getOperands();
		
		// the first operand is the command name
		mCmdRunner.execute( remainder[ 0 ], remainder );
	}
		
		void
	handleInteractive(  )
	{
		final LineReaderImpl	lineReader	= new LineReaderImpl( System.in );
		final CmdReader			reader		= new CmdReader();
		
		try
		{
			reader.goInteractive( lineReader, mCmdRunner );
		}
		catch( Throwable t )
		{
			dm( "Exception from processing commands: " + t.getMessage() );
			t.printStackTrace();
		}
	}
	
		public void
	run( final String [] args )
		throws Exception
	{
		final File	file	= JMXAdminFileNames.getPropsFile();
		mCmdEnv.load( file );
		
		initCmds();
		
			
		// if there are no arguments, start up in interactive mode
		if ( args.length == 0 || (args.length == 1 && args[ 0 ].equals( "multi" ) ) )
		{
			handleInteractive();
		}
		else
		{
			handleSingle( args );
		}
		
		// CAUTION: if a ctrl-c is received, the JVM seems to kill us half-way through
		// storing mCmdEnv, which ends up destroying it.  Pause briefly to avoid this (hack).
		Thread.sleep( 100 );
		mCmdEnv.store( file );
	}
}

