include(${CMAKE_CURRENT_LIST_DIR}/fetch_async_api_html_template.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/fetch_async_api.cmake)

function(_trailbook_ev_generate_html_from_api)
  set(options)
  set(one_value_args
      TRAILBOOK_NAME
      API_FILE
      HTML_PATH
  )
  set(multi_value_args)
  cmake_parse_arguments(
      "args"
      "${options}"
      "${one_value_args}"
      "${multi_value_args}"
      ${ARGN}
  )
  # Parameter TRAILBOOK_NAME
  #   - is required
  #   - there should be a target named trailbook_<TRAILBOOK_NAME>
  if(NOT args_TRAILBOOK_NAME)
      message(FATAL_ERROR "trailbook_ev_generate_rst_from_api: TRAILBOOK_NAME argument is required")
  endif()
  if(NOT TARGET trailbook_${args_TRAILBOOK_NAME})
      message(
          FATAL_ERROR
          "trailbook_ev_generate_rst_from_api: No target named trailbook_${args_TRAILBOOK_NAME} found."
          " Did you forget to call add_trailbook() first?"
      )
  endif()

  # Parameter API_FILE
  #   - is required
  #   - must be a absolute path
  #   - must exist
  if(NOT args_API_FILE)
      message(FATAL_ERROR "trailbook_ev_generate_rst_from_api: API_FILE argument is required")
  endif()
  if(NOT IS_ABSOLUTE "${args_API_FILE}")
      message(FATAL_ERROR "trailbook_ev_generate_rst_from_api: API_FILE must be an absolute path")
  endif()
  if(NOT EXISTS "${args_API_FILE}")
      message(FATAL_ERROR "trailbook_ev_generate_rst_from_api: API_FILE must exist")
  endif()

  # Parameter HTML_PATH
  #   - is required
  #   - must be a relative path
  if(NOT args_HTML_PATH)
      message(FATAL_ERROR "trailbook_ev_generate_html_from_api: HTML_PATH argument is required")
  endif()
  if(IS_ABSOLUTE "${args_HTML_PATH}")
      message(FATAL_ERROR "trailbook_ev_generate_html_from_api: HTML_PATH must be an relative path: ${args_HTML_PATH}")
  endif()

  get_target_property(
      TRAILBOOK_INSTANCE_BUILD_DIRECTORY
      trailbook_everest
      TRAILBOOK_INSTANCE_BUILD_DIRECTORY
  )

  get_target_property(
      TRAILBOOK_BUILD_DIRECTORY
      trailbook_everest
      TRAILBOOK_BUILD_DIRECTORY
  )

  get_filename_component(API_NAME ${args_API_FILE} NAME_WE)

  set(ASYNC_TARGET_NAME ${API_NAME}_AsyncApi)
  set(GENERATED_HTML_PATH ${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}/${args_HTML_PATH}/${API_NAME})
  set(PREVIEW_HTML_PATH ${TRAILBOOK_BUILD_DIRECTORY}/latest/reference/api/${API_NAME})
  set(COPY_FOR_PREVIEW_SENTINEL ${GENERATED_HTML_PATH}/copy_for_preview_sentinel)

  add_custom_command(
    OUTPUT
        ${GENERATED_HTML_PATH}/index.html
    COMMAND
        ${ASYNCAPI_CMD} generate fromTemplate ${args_API_FILE} ${asyncapi-html-template_SOURCE_DIR} --force-write --use-new-generator --output=${GENERATED_HTML_PATH}
    DEPENDS
        ${args_API_FILE}
    COMMENT
        "${API_NAME}: Generate AsyncApi HTML documentation"
  )

  add_custom_target(
      trailbook_${args_TRAILBOOK_NAME}_generate_html_from_api_${ASYNC_TARGET_NAME}
      DEPENDS
          ${GENERATED_HTML_PATH}/index.html
          trailbook_${args_TRAILBOOK_NAME}_stage_prepare_sphinx_source_after
          ${DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER}
          asyncapi_cli_install_target
          asyncapi_html_template_install_target
      COMMENT
          "Target to generate HTML files in ${GENERATED_HTML_PATH} from api definition ${args_API_FILE}"
  )

  set_property(
      TARGET
          trailbook_${args_TRAILBOOK_NAME}
      APPEND
      PROPERTY
          ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE
              ${GENERATED_HTML_PATH}/index.html
              trailbook_${args_TRAILBOOK_NAME}_generate_html_from_api_${ASYNC_TARGET_NAME}
  )

  add_custom_command(
    OUTPUT ${COPY_FOR_PREVIEW_SENTINEL}

    COMMAND ${CMAKE_COMMAND} -E remove_directory "${PREVIEW_HTML_PATH}"
    COMMAND ${CMAKE_COMMAND} -E make_directory "${PREVIEW_HTML_PATH}"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${GENERATED_HTML_PATH}" "${PREVIEW_HTML_PATH}"
    COMMAND ${CMAKE_COMMAND} -E touch ${COPY_FOR_PREVIEW_SENTINEL}

    DEPENDS
         ${GENERATED_HTML_PATH}/index.html

    COMMENT "Copy autogenerated AsyncAPI HTML files to a path where it is available for preview"
  )
  add_custom_target(
    trailbook_${args_TRAILBOOK_NAME}_copy_asyncapi_html_to_preview_${ASYNC_TARGET_NAME}
    DEPENDS ${COPY_FOR_PREVIEW_SENTINEL}
  )

  add_dependencies(trailbook_${args_TRAILBOOK_NAME}_copy_asyncapi_html_to_preview_${ASYNC_TARGET_NAME} trailbook_${args_TRAILBOOK_NAME}_generate_html_from_api_${ASYNC_TARGET_NAME})
  add_dependencies(trailbook_${args_TRAILBOOK_NAME}_preview trailbook_${args_TRAILBOOK_NAME}_copy_asyncapi_html_to_preview_${ASYNC_TARGET_NAME})
endfunction()


function(trailbook_ev_generate_api_doc)
    set(options)
    set(one_value_args
        TRAILBOOK_NAME
    )
    set(multi_value_args
        API_FILES)
    cmake_parse_arguments(
        "args"
        "${options}"
        "${one_value_args}"
        "${multi_value_args}"
        ${ARGN}
    )

    # Parameter TRAILBOOK_NAME
    #   - is required
    #   - there should be a target named trailbook_<TRAILBOOK_NAME>
    if(NOT args_TRAILBOOK_NAME)
        message(FATAL_ERROR "trailbook_ev_generate_api_dock: TRAILBOOK_NAME argument is required")
    endif()
    if(NOT TARGET trailbook_${args_TRAILBOOK_NAME})
        message(
            FATAL_ERROR
            "trailbook_ev_generate_api_dock: No target named trailbook_${args_TRAILBOOK_NAME} found."
            " Did you forget to call add_trailbook() first?"
        )
    endif()

    # Parameter API_FILES
    #   - is required
    if(NOT API_FILES)
        message(FATAL_ERROR "trailbook_ev_generate_api_dock: API_FILES argument is required")
    endif()

    get_target_property(
        TRAILBOOK_INSTANCE_SOURCE_DIRECTORY
        trailbook_everest
        TRAILBOOK_INSTANCE_SOURCE_DIRECTORY
    )

    # Make a list of all API's names
    set(API_NAMES "")

    foreach(API_FILE ${API_FILES})
        get_filename_component(API_NAME ${API_FILE} NAME_WE)
        set(DESTINATION_SUBFOLDER "reference/api/")
        list(APPEND API_NAMES "${API_NAME}")

        _trailbook_ev_generate_html_from_api(
            TRAILBOOK_NAME "everest"
            API_FILE "${API_FILE}"
            HTML_PATH "${DESTINATION_SUBFOLDER}"
        )
    endforeach()

    list(JOIN API_NAMES "," CSV_API_NAMES)

    set(INDEX_RST_FILE "${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}/${DESTINATION_SUBFOLDER}/autogenerated_api_index.rst")
    set(PYTHON_SCRIPT "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/process_api_template.py")
    set(TEMPLATES_DIRECTORY "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/templates")
    set(TEMPLATES_FILE "${TEMPLATES_DIRECTORY}/api_index.rst.jinja")

    add_custom_command(
        OUTPUT ${INDEX_RST_FILE}
        COMMAND ${Python3_EXECUTABLE}
                ${PYTHON_SCRIPT}
                --template-dir "${TEMPLATES_DIRECTORY}"
                --template-file "${TEMPLATES_FILE}"
                --apis "${CSV_API_NAMES}"
                --target-file "${INDEX_RST_FILE}"
        DEPENDS
            ${PYTHON_SCRIPT}
            ${TEMPLATES_FILE}
            ${TEMPLATES_DIRECTORY}/macros.jinja
            ${API_FILES}
        COMMENT
            "Generating RST index for API doc"
    )

    add_custom_target(
        trailbook_${args_TRAILBOOK_NAME}_generate_rst_api_index
        DEPENDS
            ${INDEX_RST_FILE}
            trailbook_${args_TRAILBOOK_NAME}_stage_prepare_sphinx_source_after
            ${DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER}
        COMMENT
            "Target to generate RST file ${INDEX_RST_FILE}"
    )

    set_property(
        TARGET
            trailbook_${args_TRAILBOOK_NAME}
        APPEND
        PROPERTY
            ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE
                ${INDEX_RST_FILE}
                trailbook_${args_TRAILBOOK_NAME}_generate_rst_api_index
    )
endfunction()