# 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
    "${CMAKE_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()
