/*
 * SPDX-FileCopyrightText: 2025 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */
#include <tango/common/telemetry/Scope.h>

#include <tango/internal/telemetry/SpanImplementation.h>

#include <opentelemetry/context/runtime_context.h>

namespace Tango::telemetry
{

//---------------------------------------------------------------------------------------------------------------------
// The opaque implementation classes.
//
// Such classes are usually inner classes of their associated public class but, due to a technical constraint we have
// here on one of them, we decide, for all of them, to put their respective forward declaration here.
//---------------------------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------
// ScopeImplementation
//-----------------------------------------------------------------------------------------
class ScopeImplementation final
{
  public:
    ScopeImplementation(const SpanPtr &span) noexcept :
        token(opentelemetry::context::RuntimeContext::Attach(
            opentelemetry::context::RuntimeContext::GetCurrent().SetValue(opentelemetry::trace::kSpanKey,
                                                                          span->impl->otel_span)))
    {
    }

  private:
    opentelemetry::nostd::unique_ptr<opentelemetry::context::Token> token;
};

//-----------------------------------------------------------------------------------------
// Scope::Scope
//-----------------------------------------------------------------------------------------
Scope::Scope() noexcept { }

Scope::Scope(const SpanPtr &span) noexcept
{
    // an Scope without a valid "implementation" is invalid and can't be used.
    // but, we don't throw any exception if the instantiation failed! Yes, sir. See:
    // https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f6-if-your-function-must-not-throw-declare-it-noexcep

    impl = std::make_unique<ScopeImplementation>(span);
}

//-----------------------------------------------------------------------------------------
// Scope::~Scope
//-----------------------------------------------------------------------------------------
Scope::~Scope() { }

} // namespace Tango::telemetry
