if(NOT DEFINED INPUT)
    message(FATAL_ERROR "INPUT is not defined")
endif()

if(NOT DEFINED OUTPUT)
    message(FATAL_ERROR "OUTPUT is not defined")
endif()

file(READ "${INPUT}" MANIFEST_CONTENT)

# Convert the JSON text to hex bytes so the generated C++ does not need JSON
# string escaping or raw string delimiter handling.
string(HEX "${MANIFEST_CONTENT}" MANIFEST_HEX)
string(LENGTH "${MANIFEST_HEX}" HEX_LENGTH)

set(BYTES "    ")
set(COLUMN 0)

if(HEX_LENGTH GREATER 0)
    math(EXPR LAST_INDEX "${HEX_LENGTH} - 2")

    foreach(I RANGE 0 ${LAST_INDEX} 2)
        string(SUBSTRING "${MANIFEST_HEX}" ${I} 2 BYTE_HEX)
        string(APPEND BYTES "0x${BYTE_HEX}, ")
        math(EXPR COLUMN "${COLUMN} + 1")

        if(COLUMN GREATER_EQUAL 12)
            string(APPEND BYTES "\n    ")
            set(COLUMN 0)
        endif()
    endforeach()
endif()

# Add NUL terminator for the manifest ABI buffer protocol.
string(APPEND BYTES "0x00")

get_filename_component(OUTPUT_DIR "${OUTPUT}" DIRECTORY)
file(MAKE_DIRECTORY "${OUTPUT_DIR}")

file(WRITE "${OUTPUT}" [=[
// Generated by tools/embed_umat_manifest.cmake. Do not edit.
#include "umat_manifest.h"

#include <cstddef>
#include <cstring>

namespace {
alignas(1) constexpr unsigned char kUmatManifestJson[] = {
]=])

file(APPEND "${OUTPUT}" "${BYTES}")

file(APPEND "${OUTPUT}" [=[
};
constexpr unsigned long long kUmatManifestJsonSize = sizeof(kUmatManifestJson);
} // namespace

extern "C" DLL_EXPORT int impetus_user_material_get_manifest_json(
    unsigned int requested_abi_version,
    char* buffer,
    unsigned long long buffer_size,
    unsigned long long* required_size)
{
    if (required_size == nullptr) {
        return IMPETUS_UMAT_MANIFEST_INTERNAL_ERROR;
    }

    *required_size = kUmatManifestJsonSize;

    if (requested_abi_version != IMPETUS_UMAT_MANIFEST_ABI_VERSION) {
        return IMPETUS_UMAT_MANIFEST_UNSUPPORTED_ABI;
    }

    if (buffer == nullptr || buffer_size < kUmatManifestJsonSize) {
        return IMPETUS_UMAT_MANIFEST_BUFFER_TOO_SMALL;
    }

    std::memcpy(buffer, kUmatManifestJson, static_cast<std::size_t>(kUmatManifestJsonSize));
    return IMPETUS_UMAT_MANIFEST_OK;
}
]=])
