#pragma once

#include <cstdint>
#include <string>

namespace ta::foundation::execution_path
{
    using TraceId = std::uint64_t;

    [[nodiscard]] TraceId begin(std::string feature,
                                std::string action,
                                std::string detail = {});
    [[nodiscard]] TraceId current() noexcept;
    [[nodiscard]] TraceId current_or_begin(std::string feature,
                                           std::string action,
                                           std::string detail = {});

    void step(TraceId trace_id,
              std::string component,
              std::string stage,
              std::string detail = {});
    void complete(TraceId trace_id,
                  std::string component,
                  std::string detail = {});
    void fail(TraceId trace_id,
              std::string component,
              std::string detail = {});

    class ScopedContext final
    {
    public:
        explicit ScopedContext(TraceId trace_id) noexcept;
        ~ScopedContext() noexcept;

        ScopedContext(const ScopedContext&) = delete;
        ScopedContext& operator=(const ScopedContext&) = delete;

    private:
        TraceId previous_ = 0;
    };
}
