# Copyright 2020 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.

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}/dawn.json"
             --wire-json
             "${Dawn_SOURCE_DIR}/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()
