#include <softbus_core/identity/DeviceIdentity.h>

#include <softbus_core/time/HwClock.h>

#include <chrono>
#include <iomanip>
#include <random>
#include <sstream>

namespace softbus::core {

namespace {

std::string randomHex(std::size_t bytes)
{
    static thread_local std::mt19937_64 rng{
        static_cast<std::mt19937_64::result_type>(
            std::chrono::steady_clock::now().time_since_epoch().count())};
    std::uniform_int_distribution<int> dist(0, 255);
    std::ostringstream oss;
    for (std::size_t i = 0; i < bytes; ++i) {
        oss << std::hex << std::setw(2) << std::setfill('0') << dist(rng);
    }
    return oss.str();
}

} // namespace

std::string DeviceIdentity::generateRuntimeDeviceId()
{
    return "runtime-" + randomHex(8);
}

std::string DeviceIdentity::generateTraceId()
{
    return "trace-" + randomHex(8);
}

bool DeviceIdentity::isValidRuntimeDeviceId(const std::string& id)
{
    return !id.empty() && id.rfind("runtime-", 0) == 0;
}

bool DeviceIdentity::isValidStableDeviceKey(const std::string& key)
{
    return !key.empty() && key.find('/') == std::string::npos;
}

ObjectRef DeviceIdentity::buildObjectRef(const ObjectModelTree& tree, const std::string& stableDeviceKey,
                                         const std::string& pointName)
{
    ObjectRef ref;
    ref.site = tree.site;
    ref.system = tree.system;
    ref.asset = tree.asset;
    ref.device = stableDeviceKey;
    ref.point = pointName;
    return ref;
}

} // namespace softbus::core
