/*
 * SPDX-FileCopyrightText: 2025 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */
#ifndef TANGO_COMMON_TELEMETRY_INTERFACESCOPE_H
#define TANGO_COMMON_TELEMETRY_INTERFACESCOPE_H

#include <tango/common/defines.h>

#ifdef TANGO_USE_TELEMETRY

  #include <tango/common/telemetry/Interface.h>

namespace Tango::telemetry
{

//---------------------------------------------------------------------------------------------------------------------
//! A instance of the class InterfaceScope snapshots which interface is currently attached to the current thread then
//! attaches the specified one to the thread. Uses the magic provide by the C++11 "thread_local" keyword. The interface
//! that was initially active is restored when the InterfaceScope instance goes out of scope (RAII paradigm). This is
//! mostly used by the Tango kernel. However, the users could use it in pure clients (to trace on behalf on that
//! client).
//!
//! Usage example:
//!
//!    void myClientEntryPoint()
//!    {
//!        Tango::telemetry::Configuration cfg{
//!                                 true,
//!                                 false,
//!                                 "myClientTelemetryInterface",
//!                                 "diagnostics",
//!                                 Tango::telemetry::Configuration::Client{"myClientName"},
//!                                 Tango::telemetry::DEFAULT_GRPC_TRACES_ENDPOINT};
//!
//!        Tango::telemetry::InterfacePtr tti = Tango::telemetry::InterfaceFactory::create(cfg);
//!
//!        {
//!           auto interface_scope = Tango::telemetry::InterfaceScope(tti);
//!           // tti is now the active interface
//!
//!           while (go_on)
//!           {
//!               // generate traces on behalf of the client
//!             ...
//!           }
//!        }
//!
//!        // tti is no longer the active interface
//!        // the previous one is restored (if any, otherwise use the default one)
//!    }
//!
//---------------------------------------------------------------------------------------------------------------------
class InterfaceScope
{
  public:
    InterfaceScope(InterfacePtr active_interface)
    {
        previous_interface = Tango::telemetry::Interface::get_current();

        Tango::telemetry::Interface::set_current(active_interface);
    }

    ~InterfaceScope()
    {
        Tango::telemetry::Interface::set_current(previous_interface);
    }

  private:
    InterfacePtr previous_interface{nullptr};
};

} // namespace Tango::telemetry

#endif // TANGO_USE_TELEMETRY

#endif // TANGO_COMMON_TELEMETRY_INTERFACESCOPE_H
