# Copyright 2021 The Dawn Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set(DAWN_NODE_GEN_DIR "${DAWN_BUILD_GEN_DIR}/node")
set(IDLGEN_TOOL_DIR   "${CMAKE_CURRENT_SOURCE_DIR}/tools/src/cmd/idlgen")

# idlgen() is a function that uses the tools/cmd/idlgen/main.go tool to generate
# code from an IDL file and template.
# idlgen() accepts the following named arguments:
#   TEMPLATE <path> - (required) the path to the root .tmpl file. If the
#                     template imports other templates, then these should be
#                     added to the DEPENDS argument list.
#   OUTPUT <path>   - (required) the output file path.
#   IDLS <paths>    - (at least one required) the list of input WebIDL files.
#   DEPENDS <paths> - an optional list of additional file dependencies used.
function(idlgen)
    cmake_parse_arguments(IDLGEN
        ""                # options
        "TEMPLATE;OUTPUT" # one_value_keywords
        "IDLS;DEPENDS"    # multi_value_keywords
        ${ARGN})

    if(NOT IDLGEN_TEMPLATE)
        message(FATAL_ERROR "idlgen() missing TEMPLATE argument")
    endif()
    if(NOT IDLGEN_OUTPUT)
        message(FATAL_ERROR "idlgen() missing OUTPUT argument")
    endif()
    if(NOT IDLGEN_IDLS)
        message(FATAL_ERROR "idlgen() missing IDLS argument(s)")
    endif()
    add_custom_command(
        COMMAND ${GO_EXECUTABLE} "run" "main.go"
                "--template" "${IDLGEN_TEMPLATE}"
                "--output"   "${IDLGEN_OUTPUT}"
                ${IDLGEN_IDLS}
        DEPENDS "${IDLGEN_TOOL_DIR}/main.go"
                ${IDLGEN_TEMPLATE}
                ${IDLGEN_DEPENDS}
                ${IDLGEN_IDLS}
        OUTPUT  ${IDLGEN_OUTPUT}
        WORKING_DIRECTORY ${IDLGEN_TOOL_DIR}
        COMMENT "Generating ${IDLGEN_OUTPUT}"
    )
endfunction()

add_subdirectory(binding)
add_subdirectory(interop)

add_library(dawn_node SHARED
    "Module.cpp"
)
common_compile_options(dawn_node)
set_target_properties(dawn_node PROPERTIES
    PREFIX ""
    OUTPUT_NAME "dawn"
    SUFFIX ".node"
    RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
    LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
    CXX_STANDARD 17
)
target_link_libraries(dawn_node dawn_node_binding dawn_node_interop dawn_native dawncpp dawn_proc)
target_include_directories(dawn_node PRIVATE
    "${PROJECT_SOURCE_DIR}"
    "${DAWN_THIRD_PARTY_DIR}"
    "${NODE_API_HEADERS_DIR}/include"
    "${DAWN_NODE_GEN_DIR}"
)

# To reduce the build dependencies for compiling the dawn.node targets, we do
# not use cmake-js for building, but instead just depend on node_api_headers.
# As the name suggests, node_api_headers contains just the *headers* of Napi,
# and does not provide a library to link against.
# Fortunately node_api_headers provides a list of Napi symbols exported by Node,
# which we can use to either produce weak-symbol stubs (unix) or generate a .lib
# (Windows).

# Parse the Napi symbols from ${NODE_API_HEADERS_DIR}/symbols.js
file(READ "${NODE_API_HEADERS_DIR}/symbols.js" NAPI_SYMBOLS_JS_CONTENT)
string(REGEX MATCHALL "napi_[a-z0-9_]*" NAPI_SYMBOLS "${NAPI_SYMBOLS_JS_CONTENT}")

if (WIN32)
    # Generate the NapiSymbols.def file from the Napi symbol list
    set(NAPI_SYMBOLS_DEF "${DAWN_NODE_GEN_DIR}/NapiSymbols.def")
    list(TRANSFORM NAPI_SYMBOLS PREPEND "  ")
    list(TRANSFORM NAPI_SYMBOLS APPEND "\n")
    string(REPLACE ";" "" NAPI_SYMBOLS "${NAPI_SYMBOLS}")
    string(PREPEND NAPI_SYMBOLS "LIBRARY node.exe\nEXPORTS\n")
    file(GENERATE OUTPUT "${NAPI_SYMBOLS_DEF}" CONTENT "${NAPI_SYMBOLS}")
    # Generate the NapiSymbols.lib from the NapiSymbols.def file
    set(NAPI_SYMBOLS_LIB "${DAWN_NODE_GEN_DIR}/NapiSymbols.lib")
    # Resolve path to lib.exe
    get_filename_component(VS_BIN_DIR "${CMAKE_LINKER}" DIRECTORY)
    set(LIB_EXE "${VS_BIN_DIR}/lib.exe")
    add_custom_command(
        COMMAND "${LIB_EXE}"
                "/DEF:${NAPI_SYMBOLS_DEF}"
                "/OUT:${NAPI_SYMBOLS_LIB}"
        DEPENDS "${NAPI_SYMBOLS_DEF}"
        OUTPUT  "${NAPI_SYMBOLS_LIB}"
        COMMENT "Generating ${NAPI_SYMBOLS_LIB}"
    )
    add_custom_target(napi-symbols DEPENDS "${NAPI_SYMBOLS_LIB}")
    add_dependencies(dawn_node napi-symbols)
    target_link_libraries(dawn_node "${NAPI_SYMBOLS_LIB}")
else()
    # Generate the NapiSymbols.h file from the Napi symbol list
    set(NAPI_SYMBOLS_H "${DAWN_NODE_GEN_DIR}/NapiSymbols.h")
    list(TRANSFORM NAPI_SYMBOLS PREPEND "NAPI_SYMBOL(")
    list(TRANSFORM NAPI_SYMBOLS APPEND ")\n")
    string(REPLACE ";" "" NAPI_SYMBOLS "${NAPI_SYMBOLS}")
    file(GENERATE OUTPUT "${NAPI_SYMBOLS_H}" CONTENT "${NAPI_SYMBOLS}")
    target_sources(dawn_node PRIVATE "NapiSymbols.cpp")
endif()
