//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: server.cpp
//
//Version: $Revision: 1.15 $
//
//State: $State: Exp $
//
//Date: $Date: 1999/03/11 18:58:20 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Jussi Turunen
//
//Description:
//     Instantiates the conduit tree for this demo server:
//
//
//            ___ IDL 
//      _______|________
//      \ pfTestAdapter/
//       --------------
//             |
//       --------------
//       | en/decoder |
//       --------------
//             |
//       --------------
//      / CPCSadapter  \
//      ----------------
//             |
//             ------------------------------
//
//     The pfTestAdapter instance receives a message from an IDL
//     interface and forwards it to en/decoder which encodes messages
//     from pfTestAdapter to a frame and decodes messages from
//     CPCSadapter to a otMessage::SerializedMessage.
//
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 

#include <OB/CORBA.h>
#include <OB/Util.h>
#include <typeinfo>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#ifdef HAVE_FSTREAM
#   include <fstream>
#else
#   include <fstream.h>
#endif
#include "pf/system.h"
#include "pf/conduit.h"
#include "protocol/cpcs/cpcsaadapter.h"
#include "pf/atmsocket.h"
#include "pf/debug.h"

#include "codingprotocol.h"
#include "../adapter/tastate.h"
#include "../adapter/msg_impl.h"

int main(int argc, char* argv[], char*[])
{

    if (argc == 1)
    {
        cout << "too few argumets" << endl;
        cout << "USAGE:" << endl;
        cout << "./server -v" << endl;
        cout << "./server -z port -C VCI -f reference_file <BOA options>" 
             << endl;
        cout << "Without -f switch the program assumes that "
             << "the reference file is tester.ref" << endl;
        cout << "PCO is a letter defining the PCO used in testing" << endl;
        exit(0);
    }

    pfUlong port;
    pfUlong vci;
    char testerFileRef[300];
    string PCO;

    pfSystem::init(argc, argv);

    try
    {
        // The rest of the argument handling is done here so that
        // BOA options are correctly read by the BOA.
        // port, vpi, version

        const char *options = "z:C:f:P:v";
        int opcode;
        opterr=0; // no "invalid option" messages from getopt
        //char dummy; // for char to string conversion
        
        while((opcode=getopt(argc, argv, options)) != -1)
        {
            switch (opcode)
            {
                case 'z':
                    port = atoi(optarg);
                    cout << "port was " << port << endl;
                    break;
                case 'v':
                    cout << "version: " << endl;
                    exit(0);
                    break;
                case 'C':
                    vci = atoi(optarg);
                    cout << "VCI was " << vci << endl;
                    break;
                case 'f':
                    strcpy(testerFileRef, optarg);
                    cout << "Filename was " << testerFileRef << endl;
                    break;
                case 'P':
                    PCO = string(optarg);
                    cout << "PCO was " << PCO << endl;
                default:
                    break;
            }
        }

	//
	// Create implementation object
	//
        string file1("testerAdapter");
        pfConduit adapter1;

        // IOR *MUST* be specified with the -f switch
        taState *activeState = new taState();

        adapter1 = pfTestAdapter::
            createTestAdapter(pfSystem::instance()->getORB(), 
			      file1, activeState, PCO, testerFileRef);

// Just for testing. If need be do some magic in msg_imp.cpp:
// createTestAdapter to enable these lines
#if 0
        else
        {
            taState *activeState = new taState();
            adapter1 = pfTestAdapter::
                createTestAdapter(orb, file1, activeState, PCO);
        }
#endif
        debugOutputCout();

	pfConduit codingProxy = codingProtocol::create();

	pfDevice *cpcs = 0;
	pfATMsocket *atm = new cpcsATMAdapter(16384);
	assert(atm != 0);
	cpcs = atm;
	pfConduit cpcsProxy(cpcs);
	atm->openDevice(port, 0, vci);
        atm->readDevice();
        
	adapter1.connectToA(codingProxy);
	codingProxy.connectToB(adapter1);
	codingProxy.connectToA(cpcsProxy);
	cpcsProxy.connectToA(codingProxy);

	//
	// Run implementation (alternatively, impl_is_ready could be used)
	//
	pfSystem::instance()->run();
    }
#ifdef __GNUG__
    catch(CORBA_COMM_FAILURE& ex)
#else
    catch(CORBA_SystemException& ex)
#endif
    {
	OBPrintException(ex);
	return 1;
    }
    return 0;
}
