/*
 * SPDX-FileCopyrightText: 2004 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#ifndef TANGO_SERVER_CLIENT_ADDR_H
#define TANGO_SERVER_CLIENT_ADDR_H

#include <tango/common/defines.h>
#include <tango/common/tango_const.h>

#ifdef _TG_WINDOWS_
  #include <winsock2.h>
#endif

namespace Tango
{

#define IP_ADDR_BUFFER_SIZE 80

//==================================================================================================================
// client_call_interceptor: a omniORB server-side call interceptor dealing with client info & more
//==================================================================================================================
// Description:
// Calls can be intercepted on the server just before the upcall into application code.
// This interceptor is registered with omniORB’s callDescriptor class, which is responsible for encapsulating
// the state of a call. Unlike the transport-related serverReceiveRequest, serverSendReply and serverSendException
// interceptors, the callDescriptor interceptor is invoked for all calls, even ones from colocated clients in the
// same address space. The types used for the call interceptor are defined in include/omniORB4/callDescriptor.h.
// The interceptor takes the form of a bare function with two parameters. The first parameter is a pointer to the
// callDescriptor; the second is a pointer to omniServant, which is the base class of all servant classes. The
// interceptor function must call the callDescriptor’s interceptedCall() method to pass on the call. This interception
// point allows access to various parts of omniORB’s call machinery. The callDescriptor includes access to the operation
// name and, if cast to the concrete subclass defined by the IDL compiler, the call arguments and return values too.
///==================================================================================================================
// Parameters:
// parameter d: a pointer to an omniORB callDescriptor (see include/omniORB4/callDescriptor.h for details)
// parameter s: a pointer an omniORB omniServant (base class of any Tango device dealing with CORBA low level stuffs)
///==================================================================================================================
// Comments:
// this interceptor works for both collocated and remote calls so that the client info is properly setup in any case.
// since the adoption of omniORB 4.3, it is used for both local and remote calls.
///==================================================================================================================
void client_call_interceptor(omniCallDescriptor *d, omniServant *s);

class client_addr : public omni_thread::value_t
{
  public:
    client_addr()
    {
        client_ip[0] = '\0';
        ::memset(java_ident, 0, sizeof(DevULong64) * 2);
    }

    client_addr(const char *addr)
    {
        strcpy(client_ip, addr);
    }

    ~client_addr() override { }

    client_addr(const client_addr &);
    client_addr &operator=(const client_addr &);
    bool operator==(const client_addr &);
    bool operator!=(const client_addr &);

    bool client_ident = false;
    char client_ip[IP_ADDR_BUFFER_SIZE];
    LockerLanguage client_lang = LockerLanguage::CPP;
    TangoSys_Pid client_pid = 0;
    std::string java_main_class;
    DevULong64 java_ident[2];

    int client_ip_2_client_name(std::string &) const;
    friend std::ostream &operator<<(std::ostream &o_str, const client_addr &ca);
};

} // namespace Tango

#endif // TANGO_SERVER_CLIENT_ADDR_H
