// =====================================================================
//  $Id: TExecuteCommand.cc,v 1.7 2004/03/07 10:30:28 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TExecuteCommand.cc,v $
//  Revision 1.7  2004/03/07 10:30:28  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.6  2003/11/25 19:13:10  goiwai
//  *** empty log message ***
//
//  Revision 1.5  2003/11/25 14:39:45  goiwai
//  mutexで排他制御しないといけませんね.ちょっと謎です.
//
//  Revision 1.4  2003/11/25 13:43:22  goiwai
//  とりあえず,ループ時の問題を解消しました.
//  まだ満足に動きません.特にスリープするようなコマンドに対して.
//
//  Revision 1.3  2003/10/06 17:02:37  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:17:31  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TExecuteCommand.hh"
#include "TRunManager.hh"
#include "TUserInterface.hh"

static const Tstring _name = "/system/execute";
static const Tstring _desc =
"read a macro file, execute."
"\n"
"1st argument is filename, 2nd argument(omiitable) is a number of loop, you wish."
"\n"
"CLDAQ> /system/execute sample.macro"
"\n"
"CLDAQ> /system/execute sample.macro 100";

TExecuteCommand::TExecuteCommand( TRunManager* manager )
  : TCommand( manager, _name, _desc ), theMacroFileParser()
{;}

TExecuteCommand::~TExecuteCommand()
{;}

Tvoid TExecuteCommand::Execute( const TstringList& arguments )
{
  TUserInterface* ui = theRunManager -> GetUserInterface();
  static const Tstring head = "TExecuteCommand::Execute: ";

  if ( ui ) {
    if ( arguments.empty() ) {
      ShowCommandDetail();
    } else if ( arguments.size() == 1 ) {
      Tstring filename = arguments[ 0 ];
      doExecute( ui, filename );
    } else if ( arguments.size() == 2 ) {
      Tstring filename = arguments[ 0 ];
      Tint nloop = strtol( arguments[ 1 ].c_str(), 0, 0 );
      doExecute( ui, filename, nloop );
    } else {
      Tcerr << head << "number of arguments should be 1 or 2." << Tendl;
      ShowCommandDetail();
    }
  } else {
    Tcerr << head << "UserInterface doesn't exist." << Tendl;
  }
  return;
}

//まともに機能せず
Tvoid TExecuteCommand::doExecute( TUserInterface* ui, const Tstring& filename, Tint nloop )
{
  TMacroFileParser macro( filename );
  TstringList readbuf;

  for ( Tint i = 0; i < nloop; i ++ ) {
    macro.Open();
    while ( macro.IsSuccess() ) {
      readbuf = macro.ReadLine();
      if ( macro.IsExecutable( readbuf ) ) {
	Tstring command = macro.GetCommand( readbuf );
	TstringList args = macro.GetArguments( readbuf );
	ui -> ExecuteCommand( command, args );


        //TODO
        //マクロを実行するとダメ同期処理しないとだめなんかな?
        //CLDAQ_DEBUG(command.c_str());
        //for ( Tsize_t i = 0; i < args.size(); i ++ ) {
        //CLDAQ_DEBUG(args[i].c_str());
        //}
        // mutex で排他制御しなとかもしんないですね
        //usleep(1000*1000);  //sleep はさんだところでだめ
      }
    }
  }
  macro.Close();

  return;
}

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TExecuteCommand)
#endif
