# SLX - The Simple Library Extensions Library
#
# Copyright (c) 2021 William Berry
# email: wsberry@gmail.com
# github: https://github.com/wsberry
#
# Licensed under the Apache License, Version 2.0 (the "License");
# You may freely use this source code and its projects 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 src 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.

# About:
# Implements a 'toolbox' of CMake macros and functions.

# A number of third party projects require this setting to enforce new CMake
# build behaviors when possible.
#
CMAKE_POLICY(SET CMP0054 NEW)

option(ENABLE_DIAGNOSTICS "Enable diagnostic output messages." OFF)

SET(PACKAGE_MANAGER_PATH "/usr/local/bin/brew" CACHE STRING "/usr/local/bin/brew")
SET(BREW_DEPS_DIR        "/usr/local/Cellar"   CACHE STRING "/usr/local/Cellar")

# Set up the package manager to be used.
# The Windows implementation does not use a package manager because of various issues with 'vcpkg'.
#
option(USE_PACKAGE_MANAGER "Use the available package manager (${PACKAGE_MANAGER_PATH}). Otherwise source code from a service such as GitHub." OFF)

macro(choose_package_manager)
    # Set the installed package manager and check that it
    # exists.
    #
    if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
        SET(PACKAGE_MANAGER_PATH "/usr/local/bin/brew")
    elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
        MESSAGE(FATAL_ERROR "TODO: 'choose_package_manager' NOT IMPLEMENTED FOR ${CMAKE_HOST_SYSTEM_NAME}")
        SET(PACKAGE_MANAGER_PATH "/usr/local/bin/brew")
    elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
        SET(PACKAGE_MANAGER_PATH "")
        #SET(PACKAGE_MANAGER "vcpkg")
        #if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
        #    set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
        #endif()
    else()
        MESSAGE(FATAL_ERROR "TODO: 'choose_package_manager' NOT IMPLEMENTED FOR ${CMAKE_HOST_SYSTEM_NAME}")
    endif()

    # Verify
    #
    if (EXISTS ${PACKAGE_MANAGER_PATH})
        SET(USE_PACKAGE_MANAGER ON)
    else()
        if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
            MESSAGE(FATAL_ERROR "The Homebrew Package Manager is required for the macOS operating systems...NOT FOUND: '${PACKAGE_MANAGER_PATH}'!")
        endif()
    endif()
endmacro(choose_package_manager)

# Publishes a CMake Message when 'ENABLE_DIAGNOSTICS' is ON.
#
function(diagnostic_message msg_text)
    if (ENABLE_DIAGNOSTICS)
        MESSAGE("${msg_text}")
    endif()
endfunction(diagnostic_message)

# Publish a message that indicates that the package was found.
#
function (publish_package_found pkg_name status)
    if(${status})
        MESSAGE(STATUS " - Found ${pkg_name}")
    else()
        MESSAGE("WARNING: Required dependency '${pkg_name}' was NOT FOUND")
    endif()
endfunction(publish_package_found)

# A Facade that provides an easier to use interface for
# acquiring Git repositories using the CMake FetchContent_*
# commands.
#
#       repo_name: Names the target directory for the repo.
#             url: The address of the repository being accessed.
#         version: (optional) The version to be fetched.
# installed_state: Has the repo been installed?
function(fetch_repository repo_name url version installed_state)

    if ("${installed_state}")
        publish_package_found(${repo_name} ON)
        RETURN()
    endif()

    diagnostic_message("\nCalling fetch_repository with the following args:")
    diagnostic_message("      Repo: ${repo_name}")
    diagnostic_message("       URL: ${url}")
    diagnostic_message("   Version: ${version}")
    diagnostic_message(" Installed: ${installed_state}")

    if (version STREQUAL "")
        MESSAGE(STATUS " Fetching: ${url}")
        FetchContent_Declare(${repo_name} GIT_REPOSITORY ${url})
    else()
        MESSAGE(STATUS  " Fetching: ${url} GIT_TAG ${version}")
        FetchContent_Declare(${repo_name} GIT_REPOSITORY ${url} GIT_TAG  ${version})
    endif()

    FetchContent_MakeAvailable(${repo_name})

    # IMPORTANT NOTE:
    #
    # Some repos do not follow the common GitHub director taxonomy and therefore the
    # the include directory will not be included during project generation.
    #
    if (EXISTS "${${repo_name}_SOURCE_DIR}/include")
        INCLUDE_DIRECTORIES("${${repo_name}_SOURCE_DIR}/include")
        publish_package_found(${repo_name} ON)
    else()
        publish_package_found(${repo_name} OFF)
    endif()

endfunction(fetch_repository)
