# 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(PythonInterp 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}."
    )

    set_source_files_properties(${OUTPUTS} PROPERTIES GENERATED TRUE)

    # 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()
