# -- Python library ---------
# NOTE: when we can use cmake 3.0.14 we can use FindPython
#       to locate NumPy as well, removing the need for the
#       execute_process() call

if (ENABLE_PYTHON)

    # -- Configure linking against the C library

    if (ENABLE_C)
        # if building the Python and C libraries together,
        # get the paths from the cmake target
        set(LIBFRAMEL_TARGET "framel")
        get_target_property(LIBFRAMEL_INCLUDEDIR ${LIBFRAMEL_TARGET} SOURCE_DIR)
        get_target_property(LIBFRAMEL_LIBDIR ${LIBFRAMEL_TARGET} BINARY_DIR)
        if (WIN32)
            # need the .dll file, not the .lib file
            set(LIBFRAMEL_NAME $<TARGET_FILE_NAME:${LIBFRAMEL_TARGET}>)
        else (WIN32)
            set(LIBFRAMEL_NAME $<TARGET_SONAME_FILE_NAME:${LIBFRAMEL_TARGET}>)
        endif (WIN32)
    else()
        message(CHECK_START "Looking for libframel")
        # otherwise find the installed library
        find_library(LIBFRAMEL "framel" REQUIRED)
        message(CHECK_PASS "found in ${LIBFRAMEL}")
        set(LIBFRAMEL_TARGET ${LIBFRAMEL})
        get_filename_component(LIBFRAMEL_NAME ${LIBFRAMEL} NAME)
        get_filename_component(LIBFRAMEL_LIBDIR ${LIBFRAMEL} DIRECTORY)
        # and the installed headers
        message(CHECK_START "Looking for FrameL.h")
        find_path(LIBFRAMEL_INCLUDEDIR "FrameL.h" REQUIRED)
        message(CHECK_PASS "found in ${LIBFRAMEL_INCLUDEDIR}")
    endif()

    list(TRANSFORM LIBFRAME_HEADERS PREPEND "${LIBFRAMEL_INCLUDEDIR}/")

    # -- Configure Python build

    find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
    set(Python3_VERSION_XY "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}")

    #Check if site-packages location is writable
    set(_PRODUCTION_BUILD_TYPES Release RelWithDebInfo MinSizeRel)
    if(CMAKE_BUILD_TYPE IN_LIST _PRODUCTION_BUILD_TYPES)
        # release builds must always write into a proper environment
        set(writable 0)
    else()
        execute_process(
            COMMAND "test -w ${Python3_SITEARCH}"
            RESULT_VARIABLE writable
        )
    endif()

    #If writable then put it in the site-packages directory otherwise put it in the install prefix
    if(${writable} EQUAL 0)
        set(TARGET_SP_DIR ${Python3_SITEARCH})
        set(TARGET_INSTALL_DIR ${Python3_SITEARCH}/framel)
    else()

        #If not writeable then create a python lib directory from the CMAKE_INSTALL_PREFIX
        execute_process(
            COMMAND "${Python3_EXECUTABLE}" "-c"
            "import sysconfig; print(sysconfig.get_path('platlib', vars={'base': '.', 'platbase': '.', 'platlibdir': 'lib'}))"
            RESULT_VARIABLE _Python3_RESULT
            OUTPUT_VARIABLE Python3_INSTALL_DIR
            OUTPUT_STRIP_TRAILING_WHITESPACE
        )

        # install python library
        set(TARGET_SP_DIR "${Python3_INSTALL_DIR}")
        set(TARGET_INSTALL_DIR "${Python3_INSTALL_DIR}/framel")
    endif()

    # -- Build ctypesgen wrapper

    #Check if python has ctypesgen module installed
    message(CHECK_START "Looking for ctypesgen")
    find_program(CTYPESGEN ctypesgen)
    if (NOT CTYPESGEN)
        message(CHECK_FAIL "not found")
        message(FATAL_ERROR
            " ctypesgen is not found, the python binding cannot be generated."
            " This can be installed using pip:\n"
            "    pip install ctypesgen\n"
            " or mamba:\n"
            "    mamba install -c conda-forge ctypesgen"
        )
    endif()
    message(CHECK_PASS "found: ${CTYPESGEN}")

    # build Python library using ctypesgen
    if (MSVC)
        set(CTYPESGEN_CPP "\"${CMAKE_C_COMPILER}\" -EP")
    else (MSVC)
        set(CTYPESGEN_CPP "\"${CMAKE_C_COMPILER}\" -E")
    endif (MSVC)
    set(CTYPESGEN_CMD
        "${CTYPESGEN}"
        --cpp=${CTYPESGEN_CPP}
        --output=${CMAKE_CURRENT_BINARY_DIR}/framel.py
        --include-symbols=stdout
        --library=${LIBFRAMEL_NAME}
        --compile-libdir=${LIBFRAMEL_LIBDIR}
        --runtime-libdir=${CMAKE_INSTALL_PREFIX}/${LIBRARY_DESTINATION}/
        --includedir=${LIBFRAMEL_INCLUDEDIR}
        ${LIBFRAME_HEADERS}
    )
    if (WIN32)
        list(APPEND ${CTYPESGEN_CMD} --allow-gnu-c)
    endif (WIN32)
    message(STATUS "ctypesgen will use '${CTYPESGEN_CMD}'")
    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/framel.py
        COMMENT "Building the python ctypes binding"
        COMMAND ${CTYPESGEN_CMD}
        VERBATIM
        DEPENDS ${LIBFRAMEL_TARGET}
    )
    add_custom_target(framel-python ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/framel.py)

    # -- Build Python metadata

    # create a egg-info file for pip
    set(EGG_INFO_DIR "${PROJECT_NAME}-${${PROJECT_NAME}_VERSION}-py${Python3_VERSION_XY}.egg-info")
    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/PKG-INFO" "\
Metadata-Version: 2.1
Name: ${PROJECT_NAME}
Version: ${PROJECT_VERSION}
Summary: ${PROJECT_DESCRIPTION}
Author: Benoit Mours
Author-email: benoit.mours@iphc.cnrs.fr
Home-Page: ${PROJECT_HOMEPAGE_URL}
License: LGPL-2.1-or-later
Provides: ${PROJECT_NAME}
")

    # -- Install

    install(
        FILES ${CMAKE_CURRENT_BINARY_DIR}/PKG-INFO
        DESTINATION ${TARGET_SP_DIR}/${EGG_INFO_DIR}/
    )
    install(
        FILES
        ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py
        ${CMAKE_CURRENT_SOURCE_DIR}/frvect.py
        ${CMAKE_CURRENT_BINARY_DIR}/framel.py
        DESTINATION ${TARGET_INSTALL_DIR}
    )

    # -- setup duplicate python module with old name --
    install(
        FILES ${CMAKE_CURRENT_SOURCE_DIR}/Fr.py
        DESTINATION ${TARGET_SP_DIR}
    )

endif()
