# Copyright 2020 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

find_package(Python3 REQUIRED)
message(STATUS "Dawn: using python at ${PYTHON_EXECUTABLE}")

# Check for Jinja2
if (NOT DAWN_JINJA2_DIR)
    message(STATUS "Dawn: Using system jinja2")
    execute_process(
        COMMAND ${PYTHON_EXECUTABLE} -c "import jinja2"
        RESULT_VARIABLE RET
    )
    if (NOT RET EQUAL 0)
        message(FATAL_ERROR "Dawn: Missing dependencies for code generation, please ensure you have python-jinja2 installed.")
    endif()
else()
    message(STATUS "Dawn: using jinja2 at ${DAWN_JINJA2_DIR}")
    message(STATUS "Dawn: using markupsafe at ${DAWN_MARKUPSAFE_DIR}")
endif()

# Function to invoke a generator_lib.py generator.
#  - SCRIPT is the name of the script to call
#  - ARGS are the extra arguments to pass to the script in addition to the base generator_lib.py arguments
#  - PRINT_NAME is the name to use when outputting status or errors
#  - RESULT_VARIABLE will be modified to contain the list of files generated by this generator
function(DawnGenerator)
    set(oneValueArgs SCRIPT RESULT_VARIABLE PRINT_NAME)
    set(multiValueArgs ARGS)
    cmake_parse_arguments(G "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    # Build the set of args common to all invocation of that generator.
    set(BASE_ARGS
        ${PYTHON_EXECUTABLE}
        ${G_SCRIPT}
        --template-dir
        "${DAWN_TEMPLATE_DIR}"
        --root-dir
        "${Dawn_SOURCE_DIR}"
        --output-dir
        "${DAWN_BUILD_GEN_DIR}"
        ${G_ARGS}
    )
    if (DAWN_JINJA2_DIR)
        list(APPEND BASE_ARGS --jinja2-path ${DAWN_JINJA2_DIR})
    endif()
    if (DAWN_MARKUPSAFE_DIR)
        list(APPEND BASE_ARGS --markupsafe-path ${DAWN_MARKUPSAFE_DIR})
    endif()

    # Call the generator to get the list of its dependencies.
    execute_process(
        COMMAND ${BASE_ARGS} --print-cmake-dependencies
        OUTPUT_VARIABLE DEPENDENCIES
        RESULT_VARIABLE RET
    )
    if (NOT RET EQUAL 0)
        message(FATAL_ERROR "Dawn: Failed to get the dependencies for ${G_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
    endif()

    # Ask CMake to re-run if any of the dependencies changed as it might modify the build graph.
    if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0")
        set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${DEPENDENCIES})
    endif()

    # Call the generator to get the list of its outputs.
    execute_process(
        COMMAND ${BASE_ARGS} --print-cmake-outputs
        OUTPUT_VARIABLE OUTPUTS
        RESULT_VARIABLE RET
    )
    if (NOT RET EQUAL 0)
        message(FATAL_ERROR "Dawn: Failed to get the outputs for ${G_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
    endif()

    # Add the custom command that calls the generator.
    add_custom_command(
        COMMAND ${BASE_ARGS}
        DEPENDS ${DEPENDENCIES}
        OUTPUT ${OUTPUTS}
        COMMENT "Dawn: Generating files for ${G_PRINT_NAME}."
    )

    # Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
    # generated headers in INTERFACE properties causes dependent targets to complain that they
    # cannot find the file. (because they don't see it as generated and want to check is is
    # actually on the filesystem).
    # Work around this by creating empty files placeholder generated files so that the build
    # configuration process can success.
    foreach(path ${OUTPUTS})
        if (NOT EXISTS ${path})
            string(FIND "${path}" "/" foundIndex REVERSE)
            string(SUBSTRING "${path}" 0 ${foundIndex} dir)
            file(MAKE_DIRECTORY ${dir})
            file(TOUCH ${path})
        endif()
    endforeach()

    # Return the list of outputs.
    set(${G_RESULT_VARIABLE} ${OUTPUTS} PARENT_SCOPE)
endfunction()

# Helper function to call dawn_generator.py:
#  - TARGET is the generator target to build
#  - PRINT_NAME and RESULT_VARIABLE are like for DawnGenerator
function(DawnJSONGenerator)
    set(oneValueArgs TARGET RESULT_VARIABLE)
    cmake_parse_arguments(G "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    DawnGenerator(
        SCRIPT "${Dawn_SOURCE_DIR}/generator/dawn_json_generator.py"
        ARGS --dawn-json
             "${Dawn_SOURCE_DIR}/src/dawn/dawn.json"
             --wire-json
             "${Dawn_SOURCE_DIR}/src/dawn/dawn_wire.json"
             --targets
             ${G_TARGET}
        RESULT_VARIABLE RET
        ${G_UNPARSED_ARGUMENTS}
    )

    # Forward the result up one more scope
    set(${G_RESULT_VARIABLE} ${RET} PARENT_SCOPE)
endfunction()
