//
// Derived from the Hello example of OmniBroker 1.0
//

#include <OB/CORBA.h>
#include <OB/Util.h>
#include <../../OB-1.0/naming/CosNaming.h>
#include <inap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "pf/exception.h"
#include "pf/system.h"
#include "pf/naming.h"
#include "protocol/cc/ccdebug.h"

string getTargetName(void)
{
    string targetName("ingw");
    return targetName;
}

CORBA_Object_ptr getTargetObject(void)
{
    static CORBA_Object_var target = 0;
    
    string contextName("in");
    string objectName(getTargetName());
    
    if (CORBA_is_nil(target) != 0)
    {
        CosNaming_Name_var aName = new CosNaming_Name(2);
        aName->length(2);
        aName[0].id = CORBA_string_dup(contextName.c_str());
        aName[0].kind = CORBA_string_dup("");
        aName[1].id = CORBA_string_dup(objectName.c_str());
        aName[1].kind = CORBA_string_dup(""); 
        // Obtain an object reference to the target object
        try
        {
            target = pfNaming::instance()->resolve(aName);
        }
        catch (pfMethodFailed &mf)
        {
            cerr << "At ccDpState::sendInitialDp call resolve() failed"
                 << endl;
            cerr << "Resolve name: "
                 << contextName
                 << " "
                 << objectName
                 << endl;
            mf.printInfo();
            exit(1);
        }

    }

    return target;
}

//
//Functions: send inap messages
//
//Description:
// 
//

void sendInitialDP(inap_InitialDPArgType &initialDPArg_)
{

    CORBA_Object_ptr target = getTargetObject();
    // Construct a request object by calling _request() on the target object
    CORBA_Request_var request = target->_request("initialDP");
    request->add_in_arg() <<= initialDPArg_;
    

traceSend(ccCC, ccINGW,"------initialDP",
          (char*) getTargetName().c_str());


    request->send_deferred();

    return;
}

void  sendEventReportBCSM(
    inap_EventReportBCSMArgType &eventReportBCSMArg_)
{
    // InitialDP message have been sent and target object
    // resolved?

    CORBA_Object_ptr target = getTargetObject();
    // Construct a request object by calling _request() on the target object
    CORBA_Request_var request = target->_request("eventReportBCSM");
    request->add_in_arg() <<= eventReportBCSMArg_;
    

traceSend(ccCC, ccINGW,"------eventReportBCSM",
          (char*) getTargetName().c_str());


    request->send_deferred();

    return;    
}


void sendToSCP(string &opName_, CORBA_Any any_)
{    
    CORBA_Request_var request;
    CORBA_Object_var target;
    
    CosNaming_Name_var aName = new CosNaming_Name(2);
    aName->length(2);
    aName[0].id = CORBA_string_dup("in");
    aName[0].kind = CORBA_string_dup("");
    aName[1].id = CORBA_string_dup("scp");
    aName[1].kind = CORBA_string_dup("");
    // Obtain an object reference to the target object
    try
    {
        target = pfNaming::instance()->resolve(aName);
    }
    catch(CORBA_UserException &ue)
    {
        cerr << "Can't find object in-.ingw- from NS" << endl;
        exit(1);
    }

    // Construct a request object by calling _request() on the target object
    request = target->_request(opName_.c_str());

    // Populate the request with parameters to the call
    // Obtain an empty list of name-value pairs to contain the
    // the parameters to the operation call (type NVList)
    CORBA_NVList_ptr argList = request->arguments();
      
    // Now add a NamedValue for argument
    CORBA_NamedValue_ptr argument = argList->add(CORBA_ARG_IN);
 
    // Final task is to get the Any contained in each
    // NamedValue element of the argument list and to 
    // update it with the value that is to be passed
    // for that parameter.
    CORBA_Any *value = argument->value();

    *value <<= any_;

    // Once parameters are inserted, the request can be made
    try
    {
         request->send_deferred();

      /*
         if (request->invoke())
	 {
              //cout << "invoke succeeded" << endl;     
         }
         else
         {
	      //cerr << "invoke failed" << endl;
              exit(1);
         }
	 */
    }
#ifdef __GNUG__
    catch(CORBA_COMM_FAILURE& ex)
#else
    catch(CORBA_SystemException& ex)
#endif
    {
	OBPrintException(ex);
	exit(1);
    }  

    return;
}

void sendInitialDPtest()
{    
    inap_InitialDPArgType initialDPArg;
    CORBA_Any any;
        
    inap_CallIDType callID;
            
    callID.length(4);
    CORBA_Octet i;
    for (i=0; i<4; i++) callID[i] = i+64;
      
    CORBA_Long serviceKey = 100;
    
    inap_CalledPartyNumberType calledPartyNumber;
    calledPartyNumber.length(7);
    for (i=0; i<7; i++) calledPartyNumber[i] = i+64;
    
    inap_MiscCallInfoType miscCallInfo;
    miscCallInfo.messageType = inap_request;
    miscCallInfo.dpAssignment = inap_officeBased;
    
    initialDPArg.callID = callID;
    initialDPArg.serviceKey = serviceKey;
    initialDPArg.calledPartyNumber = calledPartyNumber;
    initialDPArg.miscCallInfo = miscCallInfo;
    initialDPArg.triggerType = inap_trigger_customizedAccess;
    initialDPArg.eventTypeBCSM = inap_origAttempt;

    sendInitialDP(initialDPArg);
    
    /*
    any <<= initialDPArg;
    string opName("initialDP");
    sendToSCP(opName, any);
    */

    return;
}

int main(int argc, char* argv[], char*[])
{
    pfSystem::init(argc, argv);
    
    // Main loop
    //
    cout << "Enter 'i' to send initialDP "
         << "'e' to send eventReportBCSM "
         << "'l' to list or 'x' for exit "
         << endl;
    char c;
    do
    {
        cout << "> ";
        cin >> c;
        if(c == 'i' || c == 's')
        {
            cout << "Sending InitialDP" << endl;
            sendInitialDPtest();   
        }
        if (c == 'e')
        {
            cout << "Not implemented" << endl;
        }
        if (c == 'l')
        {
            pfNaming::instance()->listAllBindings();
        }
    }
    while(c != 'x');
    
    return 0;
}

