#!/usr/bin/env bash
 
# Path to the commit message file (provided by Git).
COMMIT_MSG_FILE=$1
 
# Ignore automatic commit messages containing ' into ' or 'Merge'.
if grep --quiet --extended-regexp " into |^Merge " "$COMMIT_MSG_FILE"; then
    exit 0
fi
 
# Read the commit message from the file.
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
 
# Check if the commit message matches the regex.
CONVENTIONAL_COMMIT_REGEX='^(feat|fix|docs|style|refactor|test|chore|build|ci|perf|revert|config)(\([a-zA-Z0-9_.-]+\))?(!)?:[[:blank:]][a-z0-9].*$'
if ! [[ $COMMIT_MSG =~ $CONVENTIONAL_COMMIT_REGEX ]]; then
    echo "ERROR: Commit message does not follow Conventional Commits format."
    echo "The commit message should be structured as follows:"
    echo
    echo "    <type>(<optional scope>): <description>"
    echo "    [optional body]"
    echo "    [optional footer(s)]"
    echo
    echo "Valid types are:"
    echo "    feat:     A new feature."
    echo "    fix:      A bug fix."
    echo "    docs:     Documentation changes."
    echo "    style:    Code style changes (formatting, missing semicolons, etc.)."
    echo "    refactor: Code refactoring (neither fixes a bug nor adds a feature)."
    echo "    test:     Adding or updating tests."
    echo "    chore:    Routine tasks like updating dependencies or build tools."
    echo "    build:    Changes affecting the build system or external dependencies."
    echo "    config:   Changes to configuration files."
    echo "    ci:       Changes to CI configuration files or scripts."
    echo "    perf:     Performance improvements."
    echo "    revert:   Reverting a previous commit."
    echo
    echo
    echo "Examples:"
    echo
    echo "    feat(auth): add login functionality"
    echo "    fix(api)!: resolve timeout issue"
    echo "    docs(readme): update installation instructions"
    echo
 
    exit 1
fi
 
# Check the commit message footers.
set -f              # turn off globbing
IFS='
'                   # split at newlines onl
 
SECOND_LINE=$(sed -n '2p' "$COMMIT_MSG_FILE")
echo $SECOND_LINE
if [[ $SECOND_LINE != "" ]]; then
    echo "ERROR: Description must be separated from the title with an empty line."
    echo
 
    exit 1
fi
 
HAS_SIGNED_OFF_BY=0
SIGNED_OFF_BY_REGEX='^Signed-off-by: .*$'
FOOTER_FORMAT_REGEX='^[A-Za-z0-9\-]+:[#A-Za-z0-9\-]'
for line in $(sed 1,1d "$COMMIT_MSG_FILE")
do
    if [[ "${line}" == "#"* ]]; then
        continue
    fi
 
    if [[ $line =~ $FOOTER_FORMAT_REGEX ]]; then
        echo "ERROR: Commit message footers format is invalid."
        echo "The footers should be structured as follows:"
        echo
        echo "    <Key>: <Value>"
        echo
        echo
        echo "Examples:"
        echo "    Refs: #EMA-12345"
        echo "    Signed-off-by: Charlie Root <root@domain.local>"
        echo "    Reviewed-by: Charlie Root <root@domain.local>"
        echo
 
        unset IFS
        set +f
        exit 1
    elif [[ $line =~ $SIGNED_OFF_BY_REGEX ]]; then
        HAS_SIGNED_OFF_BY=1
    fi
done
 
unset IFS
set +f
 
if [[ $HAS_SIGNED_OFF_BY == 0 ]]; then
        echo "ERROR: Footer \"Signed-off-by\" is required."
        echo "Please configure your .gitconfig file and use following flag: -s or --signoff"
        echo
 
        exit 1
fi
 
exit 0
