import com.remedy.arsys.api.*;
import java.io.*;
import java.util.*;

public class ThreadControlBlock
{

    ARServerUser  context = null;
    Stack         inFile = new Stack( );
    PrintWriter   outFile;
    boolean       isStdOut = false;
    PrintWriter   recordFile;
    PrintWriter   loggingFile;
    PrintWriter   resultFile;
    Stack         resultStack;
    String        buffer;
    String        args;
    boolean       primaryThread;
    String        outFileName;
    String        firstListId;
    String        secondListId;
    String        lastListId;
    String        currCommand;
    long          auxCount;
    int           numFailedBeginLoop;
    int           currentLoopDepth;
    long[]        numIterations;
    long[]        loopBeginFilePos;  
    Stack         threadHandles = null;
    SyncObject    waitObject;
    SyncObject    releaseObject;
  

    public ARServerUser getContext( )
    {
       return context;
    }

    public String getFirstListId( )
    {
        return firstListId;
    }

    public String getLastListId( )
    {
        return firstListId;
    }

    public String getSecondListId( )
    {
        return secondListId;
    }

    public String getCurrentCommand( )
    {
        return currCommand;
    }

    public Stack getResultStack( )
    {
        return resultStack;
    }

    public PrintWriter getResultFile( )
    {
        return resultFile;
    }

    public long getAuxCount( )
    {
         return auxCount;
    }

    public void setBuffer( String  content )
    {
       buffer = content;
    }

    public void closeResultFile( )
    {
        if( resultFile != null )
        {
            resultFile.close( );
            resultFile = null;
        }
    }

    public void closeResultStack( )
    {
        String temp = null;
        if( resultStack != null )
        {
            while( !resultStack.empty( ) )
           {
               temp = (String) resultStack.pop( );
               temp = null;
           }
        }
    }

    public void setAuxCount( long count )
    {
         auxCount = count;
    }

    public void setResultFile( )
    {
         resultStack = new Stack( );
    }

    public void setResultFile( String fileName ) throws IOException
    {
         resultFile = new PrintWriter( new FileOutputStream( new File( fileName ) ) );
    }
    public boolean isResultFileOpened( )
    {
         if( (JavaDriver.getOutputSetting( ) & JavaDriver.OUT_MODE_PERF_LOG_MEM ) != 0 )
         {
             if( resultStack == null )
             {
                 return false;
             }
             else
             {
                 return true;
             }
         }
         else
         {
             if( resultFile == null )
             {
                 return false;
             }
             else
             {
                return true;
             }
         }
    }

    public void writeInResultFile( String content )
    {
         if( (JavaDriver.getOutputSetting( ) & JavaDriver.OUT_MODE_PERF_LOG_MEM ) != 0 )
         {
             if( resultStack == null )
             {
                 resultStack = new Stack( );
             }
             resultStack.push( new String( content ) );
         }
         else
         {
              resultFile.println( content );
              resultFile.flush( );
         }
    }

    public void setCurrentInputFileReadingPostion( long filePosition ) throws IOException, FileNotFoundException
    {
       InputFile fp = (InputFile) inFile.pop( );
       if( fp.isFileStdIn( ) )
       {
          inFile.push( fp );
       }
       else
       {   
          // Get the current input file name 
          String name = fp.getFileName( );
      
          // Close the current input file
          fp.close( );                

          // Create the new buffered reader with the same name
          inFile.push( new InputFile( name ) );


          // Set the current input files reading position
          long currentPos = 0;          
          BufferedReader reader = getCurrentInputFile( );
          String inputLine = null;

          do
          {
             inputLine = reader.readLine( );
             currentPos = currentPos + inputLine.length( );
          }while( currentPos < filePosition );
         setCurrentInputFilePosition( currentPos );
       }       
    }

    public void setCurrentInputFilePosition( long pos )
    {
       InputFile fp = (InputFile) inFile.peek( );            
       fp.setCurrentPosition( pos );
    }

    public void addToCurrentInputFilePosition( long increment )
    {
       InputFile fp = (InputFile) inFile.peek( );            
       fp.addToCurrentPosition( increment );
    }

    public long getCurrentInputFilePos( )
    {
       InputFile fp = (InputFile) inFile.peek( );      
       return fp.getCurrentPosition( );
    }

    public void setLoopBeginFilePos( int index, long filePosition )
    {
       loopBeginFilePos[index] = filePosition;
    }

    public long getLoopBeginFilePos( int index  )
    {
       return loopBeginFilePos[index];
    }

    public void setNumberOfIterations( int index, long iterations )
    {
       numIterations[index] = iterations;
    } 

    public long getNumberOfIterations( int index )
    {
       return numIterations[index];
    }  

    public void reduceNumberOfIterations( int index )
    {
       numIterations[index] = numIterations[index] - 1;
    }

    public void incrementNumFailedBeginLoop( )
    {
       numFailedBeginLoop++;
    }

    public void reduceNumFailedBeginLoop( )
    {
       numFailedBeginLoop--;
    }

    public int getNumFailedBeginLoop( )
    {
       return numFailedBeginLoop;
    }

    public int getCurrentLoopDepth( )
    {
       return currentLoopDepth;
    }

    public void incrementCurrentLoopDepth( )
    {
       currentLoopDepth++;
    }

    public void reduceCurrentLoopDepth( )
    {
       currentLoopDepth--;
    }

    public void addThreadHandle( Object handle )
    {
       if( threadHandles == null )
       {
           threadHandles = new Stack( );
       }
       threadHandles.push( handle );
    }

    public Object getThreadHandle( )
    {
       if( ( threadHandles != null ) && (threadHandles.isEmpty( ) != true ) )
       {
          return threadHandles.peek( );
       } 
       return null;
    }

    public void deleteThreadHandle( )
    {
       if( threadHandles != null )
       {
           threadHandles.pop( );
       }
    }

    public ThreadControlBlock( )
    {
       waitObject = new SyncObject( false );
       releaseObject = new SyncObject( false );
       numIterations    = new long[10];
       loopBeginFilePos = new long[10];
       context          = new ARServerUser( );
    }

    public SyncObject getWaitObject( )
    {
       return waitObject;
    }

    public SyncObject getReleaseObject(  )
    {
       return releaseObject;
    }

    public void setWaitObjectToNull(  )
    {
       waitObject = null;
    }

    public void setReleaseObjectToNull(  )
    {
       releaseObject = null;
    }

    public boolean isCurrentInputSourceStdInput( )
    {
       InputFile fp = (InputFile) inFile.peek( );
       return fp.isFileStdIn( );
    }

    public void setAuthentication( String authString )
    {
       context.setAuthentication( authString );
    }

    public void setUser( String name )
    {
       context.setUser( new AccessNameID( name ) ) ;
    }

    public void setLocale( String locale )
    {
       context.setLocale( locale ); 
    }

    public void setPassword( String password )
    {
       context.setPassword( new AccessNameID( password ) );
    }

    public void setServer( String server )
    {
       context.setServer( server );
    }

    public String getBuffer( )
    {
       return buffer;
    }

    public void setCurrentCommand( String command )
    {
       currCommand = command;
    }

    public void setArgs( String argsString )
    {
       args = argsString;
    }

    public boolean getIsStdOut( )
    {
       return isStdOut;
    }

    public void setOutputFile( String fileName ) throws IOException
    {
        // Close the current output file if it is not stdout
        if( ( isStdOut == false ) && (outFile != null ) )
        {
            outFile.close( );
        }
  
        // open the new output file
        outFile = new PrintWriter( new FileOutputStream( new File( fileName ) ) );
        outFileName =   fileName;       
        isStdOut = false;       
    }

    public void setOutputFile( PrintWriter fp, String name, boolean stdOutFlag )
    {
        // Close the current output file if it is not stdout
        if( ( isStdOut == false ) && (outFile != null ) )
        {
             outFile.close( );
        }

        outFile = fp;
        outFileName = name;   
        isStdOut = stdOutFlag;      
    }

    public void closeInputFiles( ) throws IOException
    {
       while( !inFile.empty( ) )
       {
          InputFile file = (InputFile) inFile.pop( );
          file.close( );  
       }
    }

    public void closeOutputFile( )
    {
       if( ( outFile != null ) && ( isStdOut == false ) )
       {
           System.out.println( "isStdout is :" + isStdOut );
           System.out.println( "Closing the output file" );
           outFile.close( );
       }
       outFile = null;
       outFileName = null;
       isStdOut = false;
    }

    public void closeRecordFile( )
    {
       if( recordFile != null )
       {
           recordFile.close( );
       }
       recordFile = null;
    }

    public void setOutputFileName( String name )
    {
       outFileName = name;
    }
    public String getOutputFileName( )
    {
         return outFileName;
    }
    public void setOutputToStdOut( )
    {
         if( isStdOut == false )
         {
             if( outFile != null )
            {
                outFile.close( );
                outFile = null;              
            }
        }
        outFileName = null;

        isStdOut = true; 
        System.out.println( " In setoutputToStdout isStdOut is :" + isStdOut );
        outFile = new PrintWriter( System.out );
    }

    public void setRecordFile( PrintWriter recFile )
    {
       if( recordFile != null )
       {
          recordFile.close( );
          recordFile = null;
       }
       recordFile = recFile;
    }

    public PrintWriter getRecordFile( )
    {
       return recordFile;
    }

    public BufferedReader getCurrentInputFile( )
    {
       InputFile fp = (InputFile) inFile.peek( );            
       return  fp.getFileReader( );
    }

    public void setCurrentInputFile( InputFile ipFile )
    {
       inFile.push( ipFile );
    }

    public void setCurrentInputFile( String name ) throws FileNotFoundException
    {
       inFile.push( new InputFile( name ) );
    }

    public void setCurrentInputToStdIn( )
    {
       inFile.push( new InputFile( System.in, true ) );
    }

    public void closeCurrentInputFile( ) throws IOException
    {
        InputFile temp = (InputFile) inFile.pop( );
        temp.close( );      
        temp = null;
    }

    public boolean getPrimaryThread( )
    {
       return primaryThread;
    }

    public void setPrimaryThread( boolean primary )
    {
       primaryThread = primary;
    }

    public PrintWriter getOutFile( )
    {
         return outFile;
    }
}

