#!/usr/bin/env bash
# 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.

#set -o xtrace
set -o errexit
set -o pipefail
set -o nounset

bin="$(cd "$(dirname "$0")" > /dev/null; pwd)"

install_template_script() {
  local -r name="$1"
  local -r d_dir="$2"

  cat <<EOF > "$name"
#!/usr/bin/env bash

# This script is autogenerated by the Apache Cassandra build; DO NOT CHANGE!
# When this script is not found it will be installed automatically by the build
# If an existing script is found, that script will be reloated under ${d_dir} as 000-original.sh

# Redirect output to stderr.
exec 1>&2

# Find all scripts to run
for path in \$(find "$d_dir" -name '*.sh' | perl -e "print sort{(split '/', \\\$a)[-1] <=> (split '/', \\\$b)[-1]}<>"); do
  "\$path" "\$@"
done
EOF
  chmod a+x "$name"
}

install_hook() {
  local -r git_dir="$1"
  local -r hooks_dir="${git_dir}/hooks"
  local -r name="$2"
  local -r d_dir="${hooks_dir}/${name}.d"
  local -r trigger_on_install=$3

  mkdir "${d_dir}" &> /dev/null || true
  local -r script_name="${hooks_dir}/${name}"
  local installed=true
  if [[ -e "$script_name" ]]; then
    # was the script already installed?
    if ! grep "This script is autogenerated by the Apache Cassandra build" "$script_name" &> /dev/null ; then
      echo "$script_name found, but was not generated by the Apache Cassandra build; please remove or move to ${d_dir}/000-original.sh; creating and moving to ${d_dir} will cause it to run as expected, but won't conflict with hooks this build adds" 1>&2
      exit 1
    else
      installed=false
    fi
  fi
  # install all hooks
  cp "$bin"/git-hooks/"${name}"/* "$d_dir"/

  # install coordinator hook
  install_template_script "$script_name" "$d_dir"
  if $installed && $trigger_on_install ; then
    echo "Running script $script_name"
    "$script_name"
  fi
}

_install_hooks() {
  local git_dir
  # make sure to use --git-common-dir and not --git-dir to support worktrees
  git_dir="$(git rev-parse --git-common-dir 2> /dev/null || true)"
  if [[ -z "${git_dir:-}" ]]; then
    # not in a git repo, noop
    return 0
  fi

  # make sure hooks directory exists; does not exist by default for worktrees
  mkdir -p "${git_dir}/hooks" &> /dev/null || true

  install_hook "$git_dir" "post-checkout" true
  install_hook "$git_dir" "post-switch"   false
  install_hook "$git_dir" "pre-commit"    false
}

_git_config_set() {
  local -r name="$1"
  # only care about rc
  git config --local --get "$name" &> /dev/null
}

_install_configs() {
  # when doing pull, this makes sure submodules are updated
  _git_config_set submodule.recurse || git config --local submodule.recurse true
}

_main() {
  local git_dir
  # make sure to use --git-common-dir and not --git-dir to support worktrees
  git_dir="$(git rev-parse --git-common-dir 2> /dev/null || true)"
  # not in a git repo, noop
  [[ -z "${git_dir:-}" ]] && return 0

  _install_configs
  _install_hooks
}

_main "$@"
