// Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto.  Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once

#include <carb/flatcache/IPath.h>
#include <carb/logging/Log.h>

#include <pxr/base/tf/token.h>
#include <pxr/usd/sdf/path.h>

namespace carb
{
namespace flatcache
{

// asInt() is the same as SdfPath::_AsInt()
// Flatcache relies on asInt(a)==asInt(b) <=> a is same path as b,
// which is how SdfPath::operator== is currently defined.
// If USD changes sizeof(pxr::SdfPath), we will need to change PathC to make it
// the same size.
inline PathC asInt(const pxr::SdfPath& path)
{
    static_assert(sizeof(pxr::SdfPath) == sizeof(PathC), "Change PathC to make the same size as pxr::SdfPath");
    PathC ret;
    std::memcpy(&ret, &path, sizeof(pxr::SdfPath));
    return ret;
}

inline const PathC* asInt(const pxr::SdfPath* path)
{
    static_assert(sizeof(pxr::SdfPath) == sizeof(PathC), "Change PathC to make the same size as pxr::SdfPath");
    return reinterpret_cast<const PathC*>(path);
}

inline TokenC asInt(const pxr::TfToken& token)
{
    static_assert(sizeof(pxr::TfToken) == sizeof(TokenC), "Change TokenC to make the same size as pxr::TfToken");
    TokenC ret;
    std::memcpy(&ret, &token, sizeof(pxr::TfToken));
    return ret;
}

inline const TokenC* asInt(const pxr::TfToken* token)
{
    static_assert(sizeof(pxr::TfToken) == sizeof(TokenC), "Change TokenC to make the same size as pxr::TfToken");
    return reinterpret_cast<const TokenC*>(token);
}

// Return reference to ensure that reference count doesn't change
inline const pxr::TfToken& intToToken(const TokenC& token)
{
    static_assert(sizeof(pxr::TfToken) == sizeof(TokenC), "Change TokenC to make the same size as pxr::TfToken");

    return reinterpret_cast<const pxr::TfToken&>(token);
}

inline const pxr::SdfPath& intToPath(const PathC& path)
{
    static_assert(sizeof(pxr::SdfPath) == sizeof(PathC), "Change PathC to make the same size as pxr::SdfPath");

    return reinterpret_cast<const pxr::SdfPath&>(path);
}

inline const pxr::SdfPath* intToPath(const Path* path)
{
    static_assert(sizeof(pxr::SdfPath) == sizeof(Path), "Change Path to make the same size as pxr::SdfPath");

    return reinterpret_cast<const pxr::SdfPath*>(path);
}


}
}
