//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project/CC
//
//File: ccmanagementadapter.cpp
//
//Version: $Revision: 1.11 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/12/16 14:00:26 $
//
//Organisation:
//      University of Technology
// 
//Author:
//      Pasi Nummisalo
//
//Description:
//   ccManagementAdapter ( 1/switch = singleton) serves as
//   CORBA IDL interface adapter for management requests e.g.
//   setting triggers.
//   Registers itself to CORBA Name Service, no need for conduit
//   connections. 
//
//Copyright:
//     University of Technology
//     Laboratory of Telecommunications and Multimedia 
//      
//Licence:
//     
//
//History:
//

#include "pf/naming.h"
#include "ccmanagementadapter.h"
#include "ccodp_abandon.h"
#include "ccodp_analysedinfo.h"
#include "ccodp_routeselectfailure.h"
#include "ccodp_attempt.h"
#include "ccodp_attemptauthorized.h"
#include "ccodp_collectedinfo.h"
#include "ccodp_busy.h"
#include "ccodp_termseized.h"
#include "ccodp_noanswer.h"
#include "ccodp_answer.h"
#include "ccodp_disconnect.h"
#include "cctdp_authorized.h"
#include "sw/swswitch.h"
#include "pf/tools.h"
#include "pf/debug.h"

ccManagementAdapter *ccManagementAdapter :: _only = 0;

ccManagementAdapter::ccManagementAdapter()
    : ccIf_managementServer_skel(),
      pfAdapter(),
      _dpDataSideO(),
      _dpDataSideT(),
      _dpIter(),
      _pointCodeString()
      
{   
    pfUlong pointCode = swSwitch::instance()->getPointCode();

    _pointCodeString = pfTools::intToString(pointCode);

    // Register this to name service
    CosNaming_Name name;
    name.length(2);
    name[0].id = CORBA_string_dup(_pointCodeString.c_str());
    name[0].kind = CORBA_string_dup("");
    name[1].id = CORBA_string_dup("ssp_sms");
    name[1].kind = CORBA_string_dup("");
    
    try
    {
        pfNaming::instance()->bind(
            name,(ccIf_managementServer_skel*) this);
    }
    catch (pfMethodFailed &mf)
    {
        mf.printInfo();
        exit(1);
    }   

    // Active DPs
    
    ccDpState *dpState;

    dpState = ccOdpAttempt::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpAbandon::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpAttemptAuthorized::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpCollectedInformation::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);    
    
    dpState = ccOdpAnalysedInformation::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpRouteSelectFailure::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpCalledPartyBusy::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpTermSeized::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpNoAnswer::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpAnswer::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    dpState = ccOdpDisconnect::instance();
    _dpDataSideO[dpState->getInapType()] = ccDp(dpState);

    //++TODO++ more T side DPs can be added if needed
    dpState = ccTdpAttemptAuthorized::instance();
    _dpDataSideT[dpState->getInapType()] = ccDp(dpState);
 
    return;
}

ccManagementAdapter :: ~ccManagementAdapter()
{
    CosNaming_Name name;
    name.length(2);
    name[0].id = CORBA_string_dup(_pointCodeString.c_str());
    name[0].kind = CORBA_string_dup("");
    name[1].id = CORBA_string_dup("ssp_sms");
    name[1].kind = CORBA_string_dup("");
    
    try
    {
        pfNaming::instance()->unbind(name);
    }
    catch (pfMethodFailed &mf)
    {
        mf.printInfo();
    }

    _only = 0;
    
    return;
}

ccManagementAdapter *ccManagementAdapter :: instance(void)
{
    if (_only == 0)
    {
        _only = new ccManagementAdapter();
    }
    
    return _only;
}

//
//Function: cloneDPsForSideT
//
//Description:
//    Clone terminating DPs (state) to current call instance.
//

void ccManagementAdapter :: cloneDPsForSideT(ccMapType &dps_)
{
    dps_ = _dpDataSideT;  
    return;
}

//
//Function: cloneDPsForSideO
//
//Description:
//    Clone originating DPs (state) to current call instance.
//

void ccManagementAdapter :: cloneDPsForSideO(ccMapType &dps_)
{
    dps_ = _dpDataSideO;
    return;
}

//
//Functions: from ccIf IDL
//
//Description:
//    See IDL for more information.
//

void ccManagementAdapter :: setMessageType(ccIf_Side side_,
                                           const char *dpType_,
                                           const char *messageType_)
{
    ccMapIterType iter;
    ccMapIterType end;
    
    if (side_ == ccIf_originating)
    {
#if CC_DEBUG
cout << "setMessageType (originating) ";
#endif         
        iter = _dpDataSideO.begin();
        end = _dpDataSideO.end(); 
    }
    else
    {
#if CC_DEBUG
cout << "setMessageType (terminating) ";
#endif        
        iter = _dpDataSideT.begin();
        end = _dpDataSideT.end(); 
    }
    
    string dpTypeStr(dpType_);
    string currentTypeStr;
    string messageTypeStr(messageType_);
#if CC_DEBUG
cout << "for " << dpTypeStr << " to " << messageTypeStr << endl;
#endif    
    
    for (; iter != end; ++iter)
    {
        currentTypeStr = (*iter).second.getType();
            
        if (currentTypeStr == dpTypeStr)
        {
            (*iter).second.setMessageType(messageTypeStr);
            break;
        }
    }
    
    return;
}
        

void ccManagementAdapter :: addTrigger(ccIf_Side side_,
                                       const char *dpType_,
                                       const ccIf_TriggerType &newTrigger_)
{
    ccMapIterType iter;
    ccMapIterType end;
    
    if (side_ == ccIf_originating)
    {
#if CC_DEBUG
cout << "addTrigger (originating) ";
#endif        
        iter = _dpDataSideO.begin();
        end = _dpDataSideO.end(); 
    }
    else
    {
#if CC_DEBUG
cout << "addTrigger (terminating) ";
#endif          
        iter = _dpDataSideT.begin();
        end = _dpDataSideT.end(); 
    }
    
    string dpTypeStr(CORBA_string_dup(dpType_));

#if CC_DEBUG
    cout << "to " << dpTypeStr << endl;
#endif      
     
    for (; iter != end; ++iter)
    {
        if ((*iter).second.getType() == dpTypeStr)
        {
            (*iter).second.addTrigger(newTrigger_);
            break;
        }
    }
    return;    
}
        
void ccManagementAdapter :: deleteTrigger(ccIf_Side side_,
                                          const char *dpType_,
                                          const ccIf_TriggerType &oldTrigger_)
{
    ccMapIterType iter;
    ccMapIterType end;
    
    if (side_ == ccIf_originating)
    {
#if CC_DEBUG
cout << "deleteTrigger (originating)" << endl;
#endif        
        iter = _dpDataSideO.begin();
        end = _dpDataSideO.end(); 
    }
    else
    {
#if CC_DEBUG
cout << "deleteTrigger (terminating)" << endl;
#endif        
        iter = _dpDataSideT.begin();
        end = _dpDataSideT.end(); 
    }
    
    string dpTypeStr(CORBA_string_dup(dpType_));

#if CC_DEBUG
cout << "from " << dpTypeStr;
#endif 
    
    for (; iter != end; ++iter)
    {
        if ((*iter).second.getType() == dpTypeStr)
        {            
            (*iter).second.deleteTrigger(oldTrigger_);
            break;
        }
    }
    
    return;     
}
        
void ccManagementAdapter :: requestTDPreport(ccIf_Side side_,
                                             ccIf_TDPsType *&TDPs_)
{   
    ccIf_TDPsType tdps;
    ccIf_TDPtype tdp;
    string tmpStr;
    unsigned int size = 0;
    unsigned int index = 0;
    ccMapIterType iter;
    ccMapIterType end;
    
    if (side_ == ccIf_originating)
    {
        cout << "requestTDPreport (originating)" << endl;
        size = _dpDataSideO.size();
        tdps.length(size);
        iter = _dpDataSideO.begin();
        end = _dpDataSideO.end(); 
    }
    else
    {
        cout << "requestTDPreport (terminating)" << endl;
        size = _dpDataSideT.size();
        tdps.length(size);
        iter = _dpDataSideT.begin();
        end = _dpDataSideT.end(); 
    }
 
    for (; iter != end; ++iter)
    {
        tmpStr = (*iter).second.getType();
        tdp.type = CORBA_string_dup(tmpStr.c_str());

        tmpStr = (*iter).second.getMessageType();
        tdp.messageType = CORBA_string_dup(tmpStr.c_str());

        // Only Office and group based
        tdp.setTriggers = (*iter).second.getActiveTriggers();
        
        tdp.allowedTriggers = (*iter).second.getAllowedTriggers();
        
        tdps[index] = tdp;
        ++index;
    }

    TDPs_ = new ccIf_TDPsType(tdps);
    
    return;    
}


void ccManagementAdapter :: test(void)
{
     cout << "test" << endl;
}










