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

#include <OB/CORBA.h>
#include <OB/Util.h>
#include <OB/CosEventChannelAdmin.h>
#include <OB/CosEventComm_skel.h>

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#endif

#include <stdio.h>
#include <time.h>

#include <stdlib.h>

class PushSupplier_impl : public CosEventComm_PushSupplier_skel
{
    CosEventComm_PushConsumer_var consumer_;

public:

    PushSupplier_impl(CosEventComm_PushConsumer_ptr);
    ~PushSupplier_impl();

    void disconnect_push_supplier();

    int run();
};

PushSupplier_impl::PushSupplier_impl(CosEventComm_PushConsumer_ptr consumer)
    : consumer_(CosEventComm_PushConsumer::_duplicate(consumer))
{
    assert(!CORBA_is_nil(consumer_));
}

PushSupplier_impl::~PushSupplier_impl()
{
    consumer_ -> disconnect_push_consumer();
}

void
PushSupplier_impl::disconnect_push_supplier()
{
    consumer_ = CosEventComm_PushConsumer::_nil();
}

//
// Provide date and time
//
int
PushSupplier_impl::run()
{
    //
    // Main loop
    //
    while(true)
    {
	char str[256];
	time_t clock;

	clock = time(0);
	sprintf(str, "PushSupplier says: %s", ctime(&clock));
	str[strlen(str) - 1] = 0;

	try
	{
	    CORBA_Any any;

	    any <<= CORBA_string_dup(str);
	    consumer_ -> push(any);
	}
	catch(CORBA_SystemException& ex)
	{
	    OBPrintException(ex);
	    return 1;
	}

#ifdef WIN32
	Sleep(1000);
#else
	sleep(1);
#endif
    }

    return 0;
}

int
main(int argc, char* argv[], char*[])
{
    try
    {
        //
        // Create ORB.
        //
        CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
	
	//
	// Get event channel.
	//
	CORBA_Object_var obj;
	
	try
	{
	    obj = orb -> resolve_initial_references("EventService");
	}
	catch(const CORBA_ORB::InvalidName&)
	{
	    cerr << argv[0] << ": can't resolve `EventService'" << endl;
	    return 1;
	}
	
	if(CORBA_is_nil(obj))
	{
	    cerr << argv[0] << ": `EventService' is a nil object reference"
		 << endl;
	    return 1;
	}
	
	CosEventChannelAdmin_EventChannel_var e =
	    CosEventChannelAdmin_EventChannel::_narrow(obj);
	
	if(CORBA_is_nil(e))
	{
	    cerr << argv[0]
		 << ": `EventService' is not an EventChannel object reference"
		 << endl;
	    return 1;
	}
	
	//
	// Get ProxyPushConsumer.
	//
	CosEventChannelAdmin_SupplierAdmin_var supplierAdmin =
	    e -> for_suppliers();
	CosEventChannelAdmin_ProxyPushConsumer_var consumer =
	    supplierAdmin -> obtain_push_consumer();
	
	//
	// Connect implementation to ProxyPushConsumer.
	//
	PushSupplier_impl* supplier = new PushSupplier_impl(consumer);
	CosEventComm_PushSupplier_var dummy = supplier;
	consumer -> connect_push_supplier(CosEventComm_PushSupplier::_nil());
	
	if(supplier -> run() == 1)
	    return 1;
    }
    catch(CORBA_SystemException& ex)
    {
        OBPrintException(ex);
        return 1;
    }
 
    return 0;
}
