#!/usr/bin/env bash
set -Eeuo pipefail

AVAILABLE_ROOT="${LEGO_AVAILABLE_HOOK_ROOT:-/usr/share/lego/hooks}"
CONFIG_DIR="${LEGO_CONFIG_DIR:-/etc/lego}"

usage() {
    cat <<'USAGE'
Usage:
  lego-hook list
  lego-hook enabled
  lego-hook enable pre|post NAME [ORDER]
  lego-hook disable pre|post NAME
USAGE
}

die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
require_root() { [[ ${EUID} -eq 0 ]] || die "this operation must be run as root"; }
validate_type() { [[ "$1" == pre || "$1" == post ]] || die "hook type must be pre or post"; }
validate_name() { [[ "$1" =~ ^[A-Za-z0-9_.-]+$ ]] || die "invalid hook name: $1"; }

command="${1:-}"
case "${command}" in
    list)
        for type in pre post; do
            [[ -d "${AVAILABLE_ROOT}/${type}" ]] || continue
            while IFS= read -r path; do
                printf '%s\t%s\n' "${type}" "$(basename "${path}")"
            done < <(find "${AVAILABLE_ROOT}/${type}" -maxdepth 1 -type f -perm /111 | sort)
        done
        ;;
    enabled)
        for type in pre post; do
            enabled_dir="${CONFIG_DIR}/${type}"
            [[ -d "${enabled_dir}" ]] || continue
            while IFS= read -r path; do
                printf '%s\t%s -> %s\n' "${type}" "$(basename "${path}")" "$(readlink -f "${path}" 2>/dev/null || printf '?')"
            done < <(find "${enabled_dir}" -maxdepth 1 -type l | sort)
        done
        ;;
    enable)
        require_root
        type="${2:-}"; name="${3:-}"; order="${4:-50}"
        validate_type "${type}"; validate_name "${name}"
        [[ "${order}" =~ ^[0-9]{1,3}$ ]] || die "ORDER must be numeric"
        source="${AVAILABLE_ROOT}/${type}/${name}"
        [[ -x "${source}" ]] || die "available hook not found: ${source}"
        install -d -m 0755 "${CONFIG_DIR}/${type}"
        ln -sfn "${source}" "${CONFIG_DIR}/${type}/${order}-${name}"
        printf 'Enabled %s hook: %s\n' "${type}" "${name}"
        ;;
    disable)
        require_root
        type="${2:-}"; name="${3:-}"
        validate_type "${type}"; validate_name "${name}"
        found=false
        shopt -s nullglob
        for link in "${CONFIG_DIR}/${type}/"*"-${name}"; do
            [[ -L "${link}" ]] || continue
            rm -f -- "${link}"
            found=true
        done
        ${found} && printf 'Disabled %s hook: %s\n' "${type}" "${name}" || die "hook is not enabled: ${type}/${name}"
        ;;
    *) usage; [[ -n "${command}" ]] && exit 1 || exit 0 ;;
esac
