#include <iostream.h>
#include <sys/time.h>
#include "hello.h"
#include <mico/intercept.h>

class MyClientInterceptor : public Interceptor::ClientInterceptor {
public:
    Interceptor::Status
    initialize_request (Interceptor::LWRequest_ptr req,
			CORBA::Environment_ptr env)
    {
	/*
	 * what you can do here:
	 * - set the service context list for the request
	 * - modify the in/inout parameters of the request
	 * - piggyback extra values to the request
	 * - change the target object reference
	 * - change the operation name
	 * - answer the request yourself by filling in out parameters
	 *   or raising an exception (using env parameter) and returning
	 *   INVOKE_ABORT
	 */
	CORBA::String_var s = req->operation();
	cout << "client: init request for: " << s.in() << endl;
	return Interceptor::INVOKE_CONTINUE;
    }

    Interceptor::Status
    after_marshal (Interceptor::LWRequest_ptr req,
		   CORBA::Environment_ptr env)
    {
	/*
	 * what you can do here:
	 * - answer the request yourself by filling in out parameters
	 *   or raising an exception (using env parameter) and returning
	 *   INVOKE_ABORT
	 */
	CORBA::String_var s = req->operation();
	cout << "client: after marshal for: " << s.in() << endl;
	return Interceptor::INVOKE_CONTINUE;
    }

    Interceptor::Status
    before_unmarshal (Interceptor::LWRequest_ptr req,
		      CORBA::Environment_ptr env)
    {
	/*
	 * what you can do here:
	 * - answer the request yourself by filling in out parameters
	 *   or raising an exception (using env parameter) and returning
	 *   INVOKE_ABORT
	 */
	CORBA::String_var s = req->operation();
	cout << "client: before unmarshal for: " << s.in() << endl;
	return Interceptor::INVOKE_CONTINUE;
    }

    Interceptor::Status
    finish_request (Interceptor::LWRequest_ptr req,
		    CORBA::Environment_ptr env)
    {
	/*
	 * what you can do here:
	 * - get the service context list from the reply
	 * - modify the out/inout parameters of the request
	 * - remove piggybacked extra values from the reply
	 * - answer the request yourself by filling in out parameters
	 *   or raising an exception (using env parameter) and returning
	 *   INVOKE_ABORT
	 */
	CORBA::String_var s = req->operation();
	cout << "client: finish request for: " << s.in() << endl;
	return Interceptor::INVOKE_CONTINUE;
    }
};

int
main (int argc, char *argv[])
{
    MyClientInterceptor icept;
    icept.activate (0);

    CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, "mico-local-orb");
    CORBA::BOA_var boa = orb->BOA_init (argc, argv, "mico-local-boa");

    assert (argc == 2);
    CORBA::Object_var obj = orb->bind ("IDL:Hello:1.0", argv[1]);
    if (CORBA::is_nil (obj)) {
	cerr << "cannot bind to " << argv[1] << endl;
	return 1;
    }
    Hello_var hello = Hello::_narrow (obj);
    hello->hello ();
    return 0;
}
