//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: toveswitch_impl.cpp
//
//Version: $Revision: 1.12 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/12/16 15:30:21 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Kokkonen
//
//Description:
//      See corresponding header file.
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//     
//
//History:
//

#include <typeinfo>
#include <string>
#include "pf/naming.h"
#include "pf/error.h"
#include "pf/exception.h"
#include "pf/debug.h"
#include "toveswitch_impl.h"

toveSwitch_impl :: toveSwitch_impl(void)
    : toveSwitch_switchInterface_skel(),
      mgmtSend(),
      _otherSide(0)
{
    return;
}


toveSwitch_impl :: ~toveSwitch_impl()
{
    CORBA_release(_otherSide);

    return;
}

//
//Function: registerUserInterface
//
//Description:
//      Other side can register in with this method. If someone else 
//      has already registered in method throws toveSwitch_RegisteringError
//       exception. In version 1 there can be only one user registered in.
//
void toveSwitch_impl :: registerUserInterface(CORBA_Object_ptr iface_)
{
    if (_isUIregistered != 0)
    {
        throw toveSwitch_RegisteringError();
    }

    toveSwitch_switchInterface_ptr tmp = 
        toveSwitch_switchInterface::_narrow(iface_);

    if (CORBA_is_nil(tmp))
    {
        throw toveSwitch_RegisteringError();
    }
    _otherSide = toveSwitch_switchInterface::_duplicate(tmp);
    _isUIregistered = 1;

    receiveRegister();
    return;
}

//
//Function: unregisterUserInterface
//
//Description:
//      Other side can unregister with this method.
//
void toveSwitch_impl :: unregisterUserInterface(CORBA_Object_ptr)
{
    CORBA_release(_otherSide);
    _isUIregistered = 0;

    receiveUnRegister();
    return;
}

//
//Function: getValue
//
//Description:
//      Method that otherside can get values.
//
char* toveSwitch_impl :: getValue(const char* name_)
{
    string name = name_;

    string tmp = receiveGet(name);
    char *result = CORBA_string_dup(tmp.c_str());

    return result;
}

//
//Function: setValue
//
//Description:
//      Method that otherside can set values.
//
void toveSwitch_impl :: setValue(const char* name_, const char* value_)
{
    string name = name_;
    string value = value_;

    receiveSet(name, value);
    return;
}

//
//Function: execute
//
//Description:
//      Method that otherside can use execute.
//
void toveSwitch_impl :: execute(const char* command_,
                                toveSwitch_ParameterList& parameters_)
{
    mgmtCommand command(command_, parameters_);

    receiveExecute(command);

    return;
}

//----------------------------------------------------------------------
//               These methods belong to the user
//----------------------------------------------------------------------

//
//Function: registerIfaceToNameService
//
//Description:
//      Method that interface can register to the nameserver.
//
void toveSwitch_impl :: registerIfaceToNameService(void)
{
    try
    {
        pfNaming::instance()->bind(_name, this);
    }

    catch (pfMethodFailed &exception)
    {
        exception.printInfo();
        THROW_NETWORK_OUT_OF_ORDER;
    }

    return;
}

//
//Function: unRegisterIfaceToNameService
//
//Description:
//      Method that interface can unregister from nameserver.
//
void toveSwitch_impl :: unRegisterIfaceToNameService(void)
{
    try
    {
        pfNaming::instance()->unbind(_name);
    }

    catch (pfMethodFailed &exception)
    {
        exception.printInfo();
        THROW_NETWORK_OUT_OF_ORDER;
    }
    return;
}

//
//Function: registerToOther
//
//Description:
//      Method to register to the other, Throws THROW_NETWORK_OUT_OF_ORDER if
//      UI has already registered.
//
void toveSwitch_impl :: registerToOther(const string &name_)
{
    if (_isUIregistered != 0)
    {
        THROW_NETWORK_OUT_OF_ORDER;
    }

    CosNaming_Name name;
    name = pfNaming::parseName(name_);

    CORBA_Object_ptr otherSide = 0;

    try
    {
        otherSide = pfNaming::instance()->resolve(name);
        _otherSide = toveSwitch_switchInterface::_narrow(otherSide);

        _otherSide->registerUserInterface(this);
        _isUIregistered = 1;
    }

    catch (pfMethodFailed &exception)
    {
        CORBA_release(_otherSide);
        exception.printInfo();
        THROW_NETWORK_OUT_OF_ORDER;
    }

    catch (CORBA_Exception &exception)
    {
        _isUIregistered = 0;
        CORBA_release(_otherSide);
        string type = exception._type_id();
        debugString("toveSwitch_impl: registering to other failed", type);
        THROW_NETWORK_OUT_OF_ORDER;
    }

    return;
}

//
//Function: unRegisterToOther
//
//Description:
//      Method to unregister from other
//
void toveSwitch_impl :: unRegisterToOther(void)
{
    try
    {
        _otherSide->unregisterUserInterface(this);
    }

    catch (CORBA_Exception &exception)
    {
        _isUIregistered = 0;
        CORBA_release(_otherSide);
        
        string type = exception._type_id();
        debugString("toveSwitch_impl: unregisterToOther error", type);
        THROW_NETWORK_OUT_OF_ORDER;
    }

    _isUIregistered = 0;
    CORBA_release(_otherSide);

    return;
}

//
//Function: sendGet
//
//Description:
//      Method that user can get otherside's values.
//
string toveSwitch_impl :: sendGet(const string &name_)
{
    string result;

    try
    {
        if (_isUIregistered != 0)
        {
            char *tmp = _otherSide->getValue(name_.c_str());
            result = tmp;
            CORBA_string_free(tmp);
        }
    }

    catch (CORBA_Exception &exception)
    {
        string type = exception._type_id();
        debugString("toveSwitch_impl: sendGet error", type);
        THROW_NETWORK_OUT_OF_ORDER;
    }

    return result;
}

//
//Function: sendSet
//
//Description:
//      Method that user can set otherside's values.
//
void toveSwitch_impl :: sendSet(const string &name_, const string &value_)
{
    if (_isUIregistered != 0)
    {
        try
        {
            _otherSide->setValue(name_.c_str(), value_.c_str());
        }

        catch (CORBA_Exception &exception)
        {
            string type = exception._type_id();
            debugString("toveSwitch_impl: sendSet error", type);
            THROW_NETWORK_OUT_OF_ORDER;
        }
    }

    return;
}

//
//Function: sendExecute
//
//Description:
//      Method that user can use otherside's execute.
//
void toveSwitch_impl :: sendExecute(mgmtCommand &command_)
{
    if (_isUIregistered != 0)
    {
        const char *command = command_.getCommandName().c_str();
        toveSwitch_ParameterList list = command_.getList();

        try
        {
            _otherSide->execute(command, list);
        }

        catch (CORBA_Exception &exception)
        {
            string type = exception._type_id();
            debugString("toveSwitch_impl: sendExecute error", type);
            THROW_NETWORK_OUT_OF_ORDER;
        }
    }

    return;
}
