// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#include <OB/CORBA.h>
#include <OB/Util.h>
#include <OB/Timer.h>

#include <Simple.h>

#include <stdlib.h>
#include <errno.h>

#ifdef HAVE_FSTREAM
#   include <fstream>
#else
#   include <fstream.h>
#endif

int
main(int argc, char* argv[], char*[])
{
    try
    {
	//
	// Create ORB
	//
	CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);

	//
	// Get number of repetitions
	//
	if(argc < 2)
	{
	    cerr << "Usage: " << argv[0] << " repetitions" << endl;
	    return 1;
	}
	int reps = atoi(argv[1]);
	if(reps <= 0)
	{
	    cerr << argv[0] << ": number of repetitions must be larger than 0"
		 << endl;
	    return 1;
	}
	
	//
	// Get "I" object
	//
	const char* refFile = "I.ref";
	ifstream in; // Must use open(name), not ifstream in(name) (VC++ bug)
	in.open(refFile);
	if(in.fail())
	{
	    cerr << argv[0] << ": can't open `" << refFile << "': "
		 << strerror(errno) << endl;
	    return 1;
	}
	
	char s[1000];
	in >> s;
	
	CORBA_Object_var obj = orb -> string_to_object(s);
	assert(!CORBA_is_nil(obj));
	
	I_var i = I::_narrow(obj);
	assert(!CORBA_is_nil(i));
	
	//
        // If the server is using a thread-pool force the pool to be
        // initialized.
        //
	timeval tv = OBTimerList::timeNow();
	CORBA_Boolean exists = !(i -> _non_existent());
	assert(exists);
	tv = OBTimerList::timeSub(OBTimerList::timeNow(), tv);
	cout << "Time needed for initialization: "
	     << ((double)tv.tv_sec + (double)tv.tv_usec / 1000000.0) * 1000.0
	     << " ms" << endl;

	//
	// Main loop
	//
	tv = OBTimerList::timeNow();
	for(int j = 0; j < reps; ++j)
	    i -> f();
	tv = OBTimerList::timeSub(OBTimerList::timeNow(), tv);
	cout << "Total time needed: "
	     << ((double)tv.tv_sec + (double)tv.tv_usec / 1000000.0) * 1000.0
	     << " ms" << endl;
	cout << "Time per method call: "
	     << (((double)tv.tv_sec + (double)tv.tv_usec / 1000000.0)
		 / (double)reps) * 1000.0 << " ms" << endl;
    }
    catch(CORBA_SystemException& ex)
    {
	OBPrintException(ex);
	return 1;
    }
    
    return 0;
}

