# Ceres Solver - A fast non-linear least squares minimizer
# Copyright 2015 Google Inc. All rights reserved.
# http://ceres-solver.org/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors may be
#   used to endorse or promote products derived from this software without
#   specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Authors: keir@google.com (Keir Mierle)
#          alexs.mac@gmail.com (Alex Stewart)

# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
function(ADD_GERRIT_COMMIT_HOOK SOURCE_DIR BINARY_DIR)
  if (NOT (EXISTS ${SOURCE_DIR} AND IS_DIRECTORY ${SOURCE_DIR}))
    message(FATAL_ERROR "Specified SOURCE_DIR: ${SOURCE_DIR} does not exist, "
      "or is not a directory, cannot add Gerrit commit hook.")
  endif()
  if (NOT (EXISTS ${BINARY_DIR} AND IS_DIRECTORY ${BINARY_DIR}))
    message(FATAL_ERROR "Specified BINARY_DIR: ${BINARY_DIR} does not exist, "
      "or is not a directory, cannot add Gerrit commit hook.")
  endif()
  unset (LOCAL_GIT_DIRECTORY)
  if (EXISTS ${SOURCE_DIR}/.git)
    if (IS_DIRECTORY ${SOURCE_DIR}/.git)
      # .git directory can be found on Unix based system, or on Windows with
      # Git Bash (shipped with msysgit).
      set (LOCAL_GIT_DIRECTORY ${SOURCE_DIR}/.git)
    else(IS_DIRECTORY ${SOURCE_DIR}/.git)
      # .git is a file, this means Ceres is a git submodule of another project
      # and our .git file contains the path to the git directory which manages
      # Ceres, so we should add the gerrit hook there.
      file(READ ${SOURCE_DIR}/.git GIT_SUBMODULE_FILE_CONTENTS)
      # Strip any trailing newline characters, s/t we get a valid path.
      string(REGEX REPLACE "gitdir:[ ]*([^$].*)[\n].*" "${SOURCE_DIR}/\\1"
        GIT_SUBMODULE_GIT_DIRECTORY_PATH "${GIT_SUBMODULE_FILE_CONTENTS}")
      get_filename_component(GIT_SUBMODULE_GIT_DIRECTORY_PATH
        "${GIT_SUBMODULE_GIT_DIRECTORY_PATH}" ABSOLUTE)
      if (EXISTS ${GIT_SUBMODULE_GIT_DIRECTORY_PATH}
          AND IS_DIRECTORY ${GIT_SUBMODULE_GIT_DIRECTORY_PATH})
        set(LOCAL_GIT_DIRECTORY "${GIT_SUBMODULE_GIT_DIRECTORY_PATH}")
      endif()
    endif()
  else (EXISTS ${SOURCE_DIR}/.git)
    # TODO(keir) Add proper Windows support.
  endif (EXISTS ${SOURCE_DIR}/.git)

  if (EXISTS ${LOCAL_GIT_DIRECTORY})
    if (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
      message(STATUS "Detected Ceres being used as a git submodule, adding "
        "commit hook for Gerrit to: ${LOCAL_GIT_DIRECTORY}")
      # Download the hook only if it is not already present.
      file(DOWNLOAD https://ceres-solver-review.googlesource.com/tools/hooks/commit-msg
        ${BINARY_DIR}/commit-msg)

      # Make the downloaded file executable, since it is not by default.
      file(COPY ${BINARY_DIR}/commit-msg
        DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
        FILE_PERMISSIONS
        OWNER_READ OWNER_WRITE OWNER_EXECUTE
        GROUP_READ GROUP_WRITE GROUP_EXECUTE
        WORLD_READ WORLD_EXECUTE)
    endif (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
  endif (EXISTS ${LOCAL_GIT_DIRECTORY})
endfunction()
