#!/bin/bash

# WARNING: Please, DO NOT edit this file! It is maintained in the Repository Template (https://github.com/nhs-england-tools/repository-template). Raise a PR instead.

set -euo pipefail

# Pre-commit git hook to scan for secrets hard-coded in the codebase. This is a
# gitleaks command wrapper. It will run gitleaks natively if it is installed,
# otherwise it will run it in a Docker container.
#
# Usage:
#   $ [options] ./scan-secrets.sh
#
# Options:
#   check={whole-history,last-commit,staged-changes}  # Type of the check to run, default is 'staged-changes'
#   FORCE_USE_DOCKER=true                             # If set to true the command is run in a Docker container, default is 'false'
#   VERBOSE=true                                      # Show all the executed commands, default is 'false'
#
# Exit codes:
#   0 - No leaks present
#   1 - Leaks or error encountered
#   126 - Unknown flag

# ==============================================================================

function main() {

  cd "$(git rev-parse --show-toplevel)"

  if command -v gitleaks > /dev/null 2>&1 && ! is-arg-true "${FORCE_USE_DOCKER:-false}"; then
    dir="$PWD"
    cmd="$(get-cmd-to-run)" run-gitleaks-natively
  else
    dir="/workdir"
    cmd="$(get-cmd-to-run)" run-gitleaks-in-docker
  fi
}

# Get Gitleaks command to execute and configuration.
# Arguments (provided as environment variables):
#   dir=[project's top-level directory]
function get-cmd-to-run() {

  check=${check:-staged-changes}
  case $check in
    "whole-history")
      cmd="detect --source $dir --verbose --redact"
      ;;
    "last-commit")
      cmd="detect --source $dir --verbose --redact --log-opts -1"
      ;;
    "staged-changes")
      cmd="protect --source $dir --verbose --staged"
      ;;
  esac
  # Include base line file if it exists
  if [ -f "$dir/scripts/config/.gitleaks-baseline.json" ]; then
    cmd="$cmd --baseline-path $dir/scripts/config/.gitleaks-baseline.json"
  fi
  # Include the config file
  cmd="$cmd --config $dir/scripts/config/gitleaks.toml"

  echo "$cmd"
}

# Run Gitleaks natively.
# Arguments (provided as environment variables):
#   cmd=[command to run]
function run-gitleaks-natively() {

  # shellcheck disable=SC2086
  gitleaks $cmd
}

# Run Gitleaks in a Docker container.
# Arguments (provided as environment variables):
#   cmd=[command to run]
#   dir=[directory to mount as a volume]
function run-gitleaks-in-docker() {

  # shellcheck disable=SC1091
  source ./scripts/docker/docker.lib.sh

  # shellcheck disable=SC2155
  local image=$(name=ghcr.io/gitleaks/gitleaks docker-get-image-version-and-pull)
  # shellcheck disable=SC2086
  docker run --rm --platform linux/amd64 \
    --volume "$PWD:$dir" \
    --workdir $dir \
    "$image" \
      $cmd
}

# ==============================================================================

function is-arg-true() {

  if [[ "$1" =~ ^(true|yes|y|on|1|TRUE|YES|Y|ON)$ ]]; then
    return 0
  else
    return 1
  fi
}

# ==============================================================================

is-arg-true "${VERBOSE:-false}" && set -x

main "$@"

exit 0
