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

#.rst:
# FindSubversion
# --------------
#
# Extract information from a subversion working copy
#
# The module defines the following variables:
#
# ::
#
#   Subversion_SVN_EXECUTABLE - path to svn command line client
#   Subversion_VERSION_SVN - version of svn command line client
#   Subversion_FOUND - true if the command line client was found
#   SUBVERSION_FOUND - same as Subversion_FOUND, set for compatibility reasons
#
#
#
# The minimum required version of Subversion can be specified using the
# standard syntax, e.g. ``find_package(Subversion 1.4)``.
#
# If the command line client executable is found two macros are defined:
#
# ::
#
#   Subversion_WC_INFO(<dir> <var-prefix> [IGNORE_SVN_FAILURE])
#   Subversion_WC_LOG(<dir> <var-prefix>)
#
# ``Subversion_WC_INFO`` extracts information of a subversion working copy at a
# given location.  This macro defines the following variables if running
# Subversion's ``info`` command on ``<dir>`` succeeds; otherwise a
# ``SEND_ERROR`` message is generated. The error can be ignored by providing the
# ``IGNORE_SVN_FAILURE`` option, which causes these variables to remain
# undefined.
#
# ::
#
#   <var-prefix>_WC_URL - url of the repository (at <dir>)
#   <var-prefix>_WC_ROOT - root url of the repository
#   <var-prefix>_WC_REVISION - current revision
#   <var-prefix>_WC_LAST_CHANGED_AUTHOR - author of last commit
#   <var-prefix>_WC_LAST_CHANGED_DATE - date of last commit
#   <var-prefix>_WC_LAST_CHANGED_REV - revision of last commit
#   <var-prefix>_WC_INFO - output of command `svn info <dir>'
#
# ``Subversion_WC_LOG`` retrieves the log message of the base revision of a
# subversion working copy at a given location.  This macro defines the variable:
#
# ::
#
#   <var-prefix>_LAST_CHANGED_LOG - last log of base revision
#
# Example usage:
#
# ::
#
#   find_package(Subversion)
#   if(SUBVERSION_FOUND)
#     Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project)
#     message("Current revision is ${Project_WC_REVISION}")
#     Subversion_WC_LOG(${PROJECT_SOURCE_DIR} Project)
#     message("Last changed log is ${Project_LAST_CHANGED_LOG}")
#   endif()

find_program(Subversion_SVN_EXECUTABLE svn
  PATHS
    [HKEY_LOCAL_MACHINE\\Software\\TortoiseSVN;Directory]/bin
  DOC "subversion command line client")
mark_as_advanced(Subversion_SVN_EXECUTABLE)

if(Subversion_SVN_EXECUTABLE)
  # the subversion commands should be executed with the C locale, otherwise
  # the message (which are parsed) may be translated, Alex
  set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
  set(ENV{LC_ALL} C)

  execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} --version
    OUTPUT_VARIABLE Subversion_VERSION_SVN
    OUTPUT_STRIP_TRAILING_WHITESPACE)

  # restore the previous LC_ALL
  set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})

  string(REGEX REPLACE "^(.*\n)?svn, version ([.0-9]+).*"
    "\\2" Subversion_VERSION_SVN "${Subversion_VERSION_SVN}")

  macro(Subversion_WC_INFO dir prefix)

    cmake_parse_arguments(
      "Subversion_WC_INFO"
      "IGNORE_SVN_FAILURE"
      "" ""
      ${ARGN}
    )

    # the subversion commands should be executed with the C locale, otherwise
    # the message (which are parsed) may be translated, Alex
    set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
    set(ENV{LC_ALL} C)

    execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} info ${dir}
      OUTPUT_VARIABLE ${prefix}_WC_INFO
      ERROR_VARIABLE Subversion_svn_info_error
      RESULT_VARIABLE Subversion_svn_info_result
      OUTPUT_STRIP_TRAILING_WHITESPACE)

    if(${Subversion_svn_info_result} EQUAL 0)
      string(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*"
        "\\2" ${prefix}_WC_URL "${${prefix}_WC_INFO}")
      string(REGEX REPLACE "^(.*\n)?Repository Root: ([^\n]+).*"
        "\\2" ${prefix}_WC_ROOT "${${prefix}_WC_INFO}")
      string(REGEX REPLACE "^(.*\n)?Revision: ([^\n]+).*"
        "\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}")
      string(REGEX REPLACE "^(.*\n)?Last Changed Author: ([^\n]+).*"
        "\\2" ${prefix}_WC_LAST_CHANGED_AUTHOR "${${prefix}_WC_INFO}")
      string(REGEX REPLACE "^(.*\n)?Last Changed Rev: ([^\n]+).*"
        "\\2" ${prefix}_WC_LAST_CHANGED_REV "${${prefix}_WC_INFO}")
      string(REGEX REPLACE "^(.*\n)?Last Changed Date: ([^\n]+).*"
        "\\2" ${prefix}_WC_LAST_CHANGED_DATE "${${prefix}_WC_INFO}")
    elseif(NOT Subversion_WC_INFO_IGNORE_SVN_FAILURE)
      message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} info ${dir}\" failed with output:\n${Subversion_svn_info_error}")
    endif()

    # restore the previous LC_ALL
    set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})

  endmacro()

  macro(Subversion_WC_LOG dir prefix)
    # This macro can block if the certificate is not signed:
    # svn ask you to accept the certificate and wait for your answer
    # This macro requires a svn server network access (Internet most of the time)
    # and can also be slow since it access the svn server
    execute_process(COMMAND
      ${Subversion_SVN_EXECUTABLE} --non-interactive log -r BASE ${dir}
      OUTPUT_VARIABLE ${prefix}_LAST_CHANGED_LOG
      ERROR_VARIABLE Subversion_svn_log_error
      RESULT_VARIABLE Subversion_svn_log_result
      OUTPUT_STRIP_TRAILING_WHITESPACE)

    if(NOT ${Subversion_svn_log_result} EQUAL 0)
      message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} log -r BASE ${dir}\" failed with output:\n${Subversion_svn_log_error}")
    endif()
  endmacro()

endif()

include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Subversion REQUIRED_VARS Subversion_SVN_EXECUTABLE
                                             VERSION_VAR Subversion_VERSION_SVN )

# for compatibility
set(Subversion_FOUND ${SUBVERSION_FOUND})
set(Subversion_SVN_FOUND ${SUBVERSION_FOUND})
