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

#include <tango/common/defines.h>

#ifdef TANGO_USE_TELEMETRY

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

namespace Tango::telemetry
{

class ScopeImplementation;

//---------------------------------------------------------------------------------------------------------------------
// Scope
//---------------------------------------------------------------------------------------------------------------------
//! In telemetry, the concept of "Scope" is crucial for context management, particularly in relation to Spans.
//! A Scope essentially defines the current active Span in a specific execution thread or context. Scope is a mechanism
//! for managing the active Span in the context of an execution thread, ensuring that Spans are correctly nested and the
//! trace is accurately constructed as the program executes. This concept is integral to distributed tracing, as it aids
//! in correctly associating the work being performed with the appropriate Span. Any Span instantiated in the context of
//! Scope becomes a child on the Span activated by the Scope. A Span created out of a Scope is considered as a root
//! Span.
//---------------------------------------------------------------------------------------------------------------------
class Scope final
{
  public:
    //! Initialize a dummy scope for a null span.
    Scope() noexcept;

    //!----------------------------------------------------------------------------------------------------------------
    //! Initialize a new scope.
    //! The given span will be set as the currently active span.
    //!
    //! @param span The span to activate for the lifetime of the Scope.
    //!----------------------------------------------------------------------------------------------------------------
    Scope(const SpanPtr &span) noexcept;

    //!----------------------------------------------------------------------------------------------------------------
    //! Release the scope.
    //! The associated Span is deactivated (as a consequence, the previously active one is restored).
    //!----------------------------------------------------------------------------------------------------------------
    ~Scope();

  private:
    // opaque implementation
    std::unique_ptr<ScopeImplementation> impl;
};

//---------------------------------------------------------------------------------------------------------------------
// ScopePtr
//---------------------------------------------------------------------------------------------------------------------
using ScopePtr = std::unique_ptr<Scope>;

} // namespace Tango::telemetry

#endif // TANGO_USE_TELEMETRY

#endif // TANGO_COMMON_TELEMETRY_SCOPE_H
