#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#

# This following function is taken from
# https://github.com/Kitware/CMake/blob/master/Modules/FindProtobuf.cmake
# and modified to our compilation.
function(PROTOBUF_GENERATE_PYTHON OUTPUT)
    if(NOT ARGN)
        message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called
        without any proto files")
        return()
    endif(NOT ARGN)

    set(${OUTPUT})
    foreach(FIL ${ARGN})
        get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
        get_filename_component(FIL_WE ${FIL} NAME_WE)
        get_filename_component(PATH ${FIL} PATH)

        list(APPEND ${OUTPUT} "${CMAKE_BINARY_DIR}/python/singa/proto/${FIL_WE}_pb2.py")

        add_custom_command(
            OUTPUT "${CMAKE_BINARY_DIR}/python/singa/proto/${FIL_WE}_pb2.py"
            COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
            ARGS --python_out ${CMAKE_BINARY_DIR}/python/singa/proto
                 --proto_path ${PATH} ${ABS_FIL}
            DEPENDS ${ABS_FIL}
            COMMENT "Running Python protocol buffer compiler on ${FIL}" VERBATIM)
    endforeach()

    set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
    set(${OUTPUT} ${${OUTPUT}} PARENT_SCOPE)
endfunction()

function (create_symlinks)
    # Do nothing if building in-source
    if (${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
        return()
    endif()

    foreach (path_file ${ARGN})
        get_filename_component(folder ${path_file} PATH)

        # Create REAL folder
        #file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/${folder}")

        # Delete symlink if it exists
        file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${path_file}")

        # Get OS dependent path to use in `execute_process`
        file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${path_file}" link)
        file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${path_file}" target)

        if (UNIX)
            set(command ln -s ${target} ${link})
        else()
            set(command cmd.exe /c mklink ${link} ${target})
        endif()

        execute_process(COMMAND ${command}
                        RESULT_VARIABLE result
                        ERROR_VARIABLE output)

        if (NOT ${result} EQUAL 0)
            message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
        endif()

    endforeach(path_file)
endfunction(create_symlinks)


# generate protobuf sources
FILE(GLOB proto_files ${CMAKE_SOURCE_DIR}/src/proto/*.proto)
PROTOBUF_GENERATE_PYTHON(proto_pys ${proto_files})
#MESSAGE(STATUS "proto pys: ${proto_pys}")

# generate cxx and wrap.py
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/singa/proto)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/rafiki)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/src/api)

IF(USE_PYTHON3)
	SET(SWIG_PYTHON3 "-py3")
ELSE()
	SET(SWIG_PYTHON3 "")
ENDIF()

execute_process(
    COMMAND swig -c++ -python ${SWIG_PYTHON3} -I${CMAKE_SOURCE_DIR}/include
    -outdir ${CMAKE_BINARY_DIR}/python/singa
    -o ${CMAKE_BINARY_DIR}/src/api/singa_wrap.cxx
    ${CMAKE_SOURCE_DIR}/src/api/singa.i)

set(python_srcs "${CMAKE_BINARY_DIR}/src/api/singa_wrap.cxx")

#Create symlinks for all python source files  Do not omit !!!RELATIVE!!!
file(GLOB_RECURSE python_source_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.py)
create_symlinks(${python_source_files})


execute_process(
    COMMAND ${PYTHON_EXECUTABLE} -c "from __future__ import print_function; import numpy; print(numpy.get_include())"
    OUTPUT_VARIABLE NUMPY_INCLUDE_DIR)

#message(status "numpy path ${NUMPY_INCLUDE_DIR}")

IF(USE_CUDA)
# remain this custom command to avoid cuda objs can't find
ADD_CUSTOM_COMMAND(
    OUTPUT ${global_cuda_objs}
    COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/"
    )
ENDIF(USE_CUDA)

ADD_LIBRARY(_singa_wrap SHARED $<TARGET_OBJECTS:singa_objects>  ${python_srcs} ${proto_pys} ${global_cuda_objs})

# For MacOS Python3.6 is already linked into python executable, hence no need to link python3.6 into Singa.
IF(APPLE)
    TARGET_LINK_LIBRARIES(_singa_wrap ${SINGA_LINKER_LIBS})    
    SET_TARGET_PROPERTIES(_singa_wrap PROPERTIES PREFIX "" 
                                                 LINK_FLAGS "-undefined dynamic_lookup" 
                                      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/python/singa)
ELSE()
    TARGET_LINK_LIBRARIES(_singa_wrap ${SINGA_LINKER_LIBS} ${PYTHON_LIBRARIES})    
    SET_TARGET_PROPERTIES(_singa_wrap PROPERTIES PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/python/singa)
ENDIF()

TARGET_INCLUDE_DIRECTORIES(_singa_wrap PRIVATE ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR})

#SETUP
SET(SETUP_PY_IN "setup.py.in")
SET(SETUP_PY    "${CMAKE_BINARY_DIR}/python/setup.py")
CONFIGURE_FILE(${SETUP_PY_IN} ${SETUP_PY})

#create python/singa/proto/__init__.py
FILE(WRITE ${CMAKE_BINARY_DIR}/python/singa/proto/__init__.py "")
IF(APPLE)
  ADD_CUSTOM_TARGET(
    change_suffix ALL
    COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_BINARY_DIR}/python/singa/_singa_wrap.dylib" "${CMAKE_BINARY_DIR}/python/singa/_singa_wrap.so"
    COMMENT "change .dylib to .so in mac system"
  )
  ADD_DEPENDENCIES(change_suffix _singa_wrap)
ENDIF(APPLE)
