//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: sscopserver.cpp
//
//Version: $Revision: 1.11 $
//
//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/
//       --------------
//             |
//       ------------------
//       |USSCF and SSCOP |
//       ------------------
//             |
//       --------------
//      / CPCSadapter  \
//      ----------------
//             |
//             ------------------------------  
//
//      
//      pfTestAdapter is used to implement the implicit send operation
//      by reacting to send() request by sending the requested PDU
//      to USSCF or SSCOP. USSCF and SSCOP are created using the method
//      saalConnection::createUNIConnection(). This is the IUT side of
//      the testing configuration.
//
//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/saal/saalunilink.h"
#include "protocol/cpcs/cpcsaadapter.h"
#include "pf/atmsocket.h"
#include "pf/debug.h"

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


int main(int argc, char* argv[], char*[])
{
    if (argc == 1)
    {
        cout << "too few argumets" << endl;
        cout << "USAGE:" << endl;
        cout << "./sscopserver -v" << endl;
        cout << "./sscopserver -z port -C VCI -P PCO <BOA options>" << endl;
        cout << "PCO is a letter defining the PCO used in testing" << endl;
        exit(0);
    }
    
    pfSystem::init(argc, argv);

    pfUlong port;
    pfUlong vci;
    string dummyPeerName("forwarder.ref");
    string PCO;

    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:P:v";
        int opcode;
        opterr=0; // no "invalid option" messages from getopt
        
        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 'P':
                    PCO = string(optarg);
                    cout << "PCO was " << PCO << endl;                    
                default:
                    break;
            }
        }

	//
	// Create implementation object
	//

        // CPCS <-> SSCOP <-> <-> USSCF <-> pfTestAdapter
        string file2("IUTAdapter");
        taState *activeState = taState::instance();
        pfConduit adapter1 =
            pfTestAdapter::createTestAdapter(
                pfSystem::instance()->getORB(), 
                file2, activeState, PCO, dummyPeerName);

        // for testing purposes
        debugOutputCout();
        
        cout << "port " << port << " VCI " << vci << endl;
        // This configuration reacts OK to uaalUpInputs
        saalUNIlink *connection =
            saalUNIlink::createATMUNIlink(0, port, 0, vci, 16384);
        
        // proxy conduit for UNIlink
        pfConduit uniLink = connection->getConduit();

	adapter1.connectToA(uniLink);
	uniLink.connectToB(adapter1);

	//
	// 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;
}

