# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

# This function handles pushing all of the test files needed to the device.
# It places the data files in the object store and makes links to them from
# the appropriate directories.
#
# This function accepts the following named parameters:
# DIRS          : one or more directories needed for testing.
# FILES         : one or more files needed for testing.
# LIBS          : one or more libraries needed for testing.
# DIRS_DEST     : specify where the directories should be installed.
# FILES_DEST    : specify where the files should be installed.
# LIBS_DEST     : specify where the libraries should be installed.
# DEV_OBJ_STORE : specify where the actual data files should be placed.
# DEV_TEST_DIR  : specify the root file for the module test directory.
# The DEV_OBJ_STORE and DEV_TEST_DIR variables are required.

# The parameters to this function should be set to the list of directories,
# files, and libraries that need to be installed prior to testing.
function(android_push_test_files_to_device)

  # The functions in the module need the adb executable.
  find_program(adb_executable adb)
  if(NOT adb_executable)
    message(FATAL_ERROR "could not find adb")
  endif()

  function(execute_adb_command)
    execute_process(COMMAND ${adb_executable} ${ARGN} RESULT_VARIABLE res_var OUTPUT_VARIABLE out_var ERROR_VARIABLE err_var)
    set(out_var ${out_var} PARENT_SCOPE)
    if(res_var)
      string(REGEX REPLACE ";" " " com "${ARGN}")
      message(FATAL_ERROR "Error occured during adb command: adb ${com}\nError: ${err_var}.")
    endif()
  endfunction()

  # Checks to make sure that a given file exists on the device. If it does,
  # if(file_exists) will return true.
  macro(check_device_file_exists device_file file_exists)
    set(${file_exists} "")
    execute_process(
      COMMAND ${adb_executable} shell ls ${device_file}
      OUTPUT_VARIABLE out_var ERROR_VARIABLE out_var)
    if(NOT out_var) # when a directory exists but is empty the output is empty
      set(${file_exists} "YES")
    else()
      string(FIND ${out_var} "No such file or directory" no_file_exists)
      if(${no_file_exists} STREQUAL "-1") # -1 means the file exists
        set(${file_exists} "YES")
      endif()
    endif()
  endmacro()

  # Checks to see if a filename matches a regex.
  function(filename_regex filename reg_ex)
    string(REGEX MATCH ${reg_ex} filename_match ${filename})
    set(filename_match ${filename_match} PARENT_SCOPE)
  endfunction()

  # If a file with given name exists in the CMAKE_BINARY_DIR then use that file.
  # Otherwise use the file with root in CMAKE_CURRENT_SOURCE_DIR.
  macro(set_absolute_path relative_path absolute_path)
    set(${absolute_path} ${arg_src_dir}/${relative_path})
    if(EXISTS ${CMAKE_BINARY_DIR}/${relative_path})
      set(${absolute_path} ${CMAKE_BINARY_DIR}/${relative_path})
    endif()
    if(NOT EXISTS ${${absolute_path}})
      if(EXISTS ${relative_path})
        set(${absolute_path} ${relative_path})
      else()
        message(FATAL_ERROR "Cannot find file for specified path: ${relative_path}")
      endif()
    endif()
  endmacro()

  # This function pushes the data into the device object store and
  # creates a link to that data file in a specified location.
  #
  # This function requires the following un-named parameters:
  # data_path        : absolute path to data to load into dev obj store.
  # dev_object_store : absolute path to the device object store directory.
  # link_origin      : absolute path to the origin of the link to the dev obj store data file.
  function(push_and_link data_path dev_object_store link_origin)
    FILE(SHA1 ${data_path} hash_val)
    set(obj_store_dst ${dev_object_store}/${hash_val})
    check_device_file_exists(${obj_store_dst} obj_store_file_exists)
    # TODO: Verify that the object store file is indeed hashed correctly. Could use md5.
    if(NOT obj_store_file_exists)
      execute_adb_command(push ${data_path} ${obj_store_dst})
    endif()
    check_device_file_exists(${link_origin} link_exists)
    if(link_exists)
      execute_adb_command(shell rm -f ${link_origin})
    endif()
    foreach(ex ${arg_no_link_regex})
      filename_regex(${data_path} ${ex})
      LIST(APPEND match_ex ${filename_match})
    endforeach()
    if(match_ex)
      execute_adb_command(shell cp ${obj_store_dst} ${link_origin})
    else()
      execute_adb_command(shell ln -s ${obj_store_dst} ${link_origin})
    endif()
  endfunction()

  #----------------------------------------------------------------------------
  #--------------------Beginning of actual function----------------------------
  #----------------------------------------------------------------------------
  set(oneValueArgs FILES_DEST LIBS_DEST DEV_TEST_DIR DEV_OBJ_STORE)
  set(multiValueArgs FILES LIBS)
  cmake_parse_arguments(_ptd "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  # Setup of object store and test dir.
  check_device_file_exists(${_ptd_DEV_OBJ_STORE} dev_obj_store_exists)
  if(NOT dev_obj_store_exists)
    execute_adb_command(shell mkdir -p ${_ptd_DEV_OBJ_STORE})
  endif()
  check_device_file_exists(${_ptd_DEV_TEST_DIR} test_dir_exists)
  if(test_dir_exists)
    # This is protected in the SetupProjectTests module.
    execute_adb_command(shell rm -r ${_ptd_DEV_TEST_DIR})
  endif()
  execute_adb_command(shell mkdir -p ${_ptd_DEV_TEST_DIR})

  # Looping over the various types of test data possible.
  foreach(TYPE ${multiValueArgs})
    if(_ptd_${TYPE})

      # determine if the data type destination has been explicitly specified.
      if(_ptd_${TYPE}_DEST)
        set(dest ${_ptd_${TYPE}_DEST})
      else()
        if(${TYPE} STREQUAL LIBS)
          set(dest ${_ptd_DEV_TEST_DIR}/lib)
        else()
          set(dest ${_ptd_DEV_TEST_DIR})
        endif()
      endif()
      execute_adb_command(shell mkdir -p ${dest})

      # Loop over the files passed in
      foreach(relative_path ${_ptd_${TYPE}})
        # The absolute path can be through the source directory or the build directory.
        # If the file/dir exists in the build directory that version is chosen.
        set_absolute_path(${relative_path} absolute_path)
        # Need to transfer all data files in the data directories to the device
        # except those explicitly ignored.
        if(${TYPE} STREQUAL FILES)
          get_filename_component(file_dir ${relative_path} DIRECTORY)
          # dest was determined earlier, relative_path is a dir, file is path from relative path to a data
          set(cur_dest ${dest}/${relative_path})
          set(on_dev_dir ${dest}/${file_dir})
          execute_adb_command(shell mkdir -p ${on_dev_dir})
          if(IS_SYMLINK ${absolute_path})
            get_filename_component(real_data_origin ${absolute_path} REALPATH)
            push_and_link(${real_data_origin} ${_ptd_DEV_OBJ_STORE} ${cur_dest})
          else()
            push_and_link(${absolute_path} ${_ptd_DEV_OBJ_STORE} ${cur_dest})
          endif()
        else() # LIBS
          execute_adb_command(push ${absolute_path} ${dest})
        endif()
      endforeach()
    endif()
  endforeach()
endfunction()

android_push_test_files_to_device(
  FILES_DEST ${arg_files_dest}
  LIBS_DEST ${arg_libs_dest}
  DEV_TEST_DIR ${arg_dev_test_dir}
  DEV_OBJ_STORE ${arg_dev_obj_store}
  FILES ${arg_files}
  LIBS ${arg_libs}
  )
