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

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

#include <Hello_impl.h>

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

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

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

//
// This viewer class dumps output to a file in order to capture
// ORBacus diagnostic information. It's very important to use this
// class with the factory, since the factory expects STDOUT to be used
// for the IOR of the Hello server. No other data should be dumped to
// STDOUT during the execution of the server.
//
class OBFileViewer : public OBMessageViewer
{
    FILE* fp_;

protected:

    OBFileViewer(const char* file)
    {
	fp_ = fopen(file, "a");
	assert(fp_ != 0);
    }
    
    ~OBFileViewer()
    {
	fclose(fp_);
    }

public:

    static OBMessageViewer* instance(const char* file)
    {
        if(!instance_)
            instance_ = new OBFileViewer(file);
        return instance_;
    }
    
    virtual void message(const char* msg)
    {
	time_t now = time(0);
	struct tm* tm = localtime(&now);
	char tbuf[128];
	strftime(tbuf, sizeof(tbuf), "%c", tm);
	fprintf(fp_, "%s: %s\n", tbuf, msg);
	fflush(fp_);
    }
};

int
main(int argc, char* argv[], char*[])
{
    try
    {
	//
	// Create file viewer instance.
	//
	OBFileViewer::instance("hello.log");

	//
	// Create ORB and BOA. The BOA runs in blocking mode, so that
	// the server exits then the client disconnects.
	//
	CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
	CORBA_BOA_var boa = orb -> BOA_init(argc, argv);
	boa -> conc_model(CORBA_BOA::ConcModelBlocking);
	
	//
	// Create implementation object
	//
	Hello_var p = new Hello_impl;
	
	//
	// Initialize the servers, and ask the IIOP acceptor to
	// listen, *before* writing the IOR down the pipe so that the
	// connection is ready to use immediately upon writing the
	// IOR. We also need to ask the IIOP acceptor to listen.
	//
	boa -> create_new_servers();
        OCI_AccRegistry_var registry = boa -> get_acc_registry();
        OCI_AcceptorSeq_var acceptors = registry -> get_acceptors();
        for(CORBA_ULong i = 0 ; i < acceptors -> length() ; i++)
            if(acceptors[i] -> tag() == IOP_TAG_INTERNET_IOP)
                acceptors[i] -> listen();

	//
	// Display reference to stdout.
	//
	CORBA_String_var s = orb -> object_to_string(p);
	cout << s;
	cout << flush;
	
	//
	// Run implementation
	//
	boa -> impl_is_ready(CORBA_ImplementationDef::_nil());
    }
    catch(CORBA_SystemException& ex)
    {
	OBPrintException(ex);
	return 1;
    }

    return 0;
}
