#!/bin/sh
# Syntax:
#   $0 <path-to-top_srcdir> <versioninfo-stamp-file>
#
# <path-to-top_srcdir> may be relative
# <versioninfo-stamp-file> is relative to the dist top_srcdir
#
# Test this script by running something like
#     rm -rf autom4te.cache/ && autoreconf -vis . && sed -n "/^# Generated by GNU/p" configure
#
# On error handling
# -----------------
#
# If we run into an error, we write an error message to stderr and exit
# with a non-0 code. The caller can then check the exit code, and the
# user can read the message from stderr.


# Parse the command line arguments
prog="$(basename "$0")"
top_srcdir="${1-.}"
versioninfo_stamp="${2-versioninfo-stamp}"


# global settings
verbose=false


# Usage example:
#   ret_error "Something is wrong: answer != 42"
ret_error() {
    printf "$prog: error: %s\n" "$1" >&2
    exit 1
}


# Usage examples:
#   ret_ok "7.3"
#   ret_ok "7.3" "20231231"
#   ret_ok "7.3" "20231231" "0123abcd"
#   ret_ok "7.3" "20231231" "0123abcd" "4567cdef"
ret_ok() {
    if $verbose; then
	printf "$prog: version info from cmake/git: %s\n" "$*" >&2
    fi
    printf "%s\n" "$@"
    exit 0
}


# Usage example:
#  ret_ok_file "$top_srcdir/$versioninfo_stamp"
ret_ok_file() {
    if $verbose; then
	printf "$prog: version information from file: %s\n" "$1" >&2
    fi
    cat "$1"
    exit 0
}


# Uncomment the following line to help debug the error case
# ret_error "Some error happened for testing purposes"


test -d "$top_srcdir" || \
    ret_error "Could not change to top_srcdir '$1'"


# If this is a "make dist" source tree, use info from versioninfo_stamp file.
if test -f "$top_srcdir/$versioninfo_stamp"; then
    ret_ok_file "$top_srcdir/$versioninfo_stamp"
fi


# This must be part of a git checkout or an expanded github snapshot tarball.
test -f "$top_srcdir/../CMakeLists.txt" || \
    ret_error "top-level avrdude CMakeLists.txt file not found"


# Find and parse "project(...)" line in top-level CmakeLists.txt file
if PROJECT_VERSION="$(${SED-sed} -n 's/project(avrdude[[:space:]]\{1,\}VERSION[[:space:]]\{1,\}\([0-9\.]\{1,\}\)[[:space:]]\{1,\}.*/\1/p' "$top_srcdir/../CMakeLists.txt")"; then
    :
else
    ret_error "Error parsing top-level avrdude 'CMakeLists.txt'."
fi

test -n "$PROJECT_VERSION" || \
    ret_error "Cannot find project(...) in top-level avrdude 'CMakeLists.txt'"


# Parse libavrdude library version from CMakeLists.txt
tmp="$(${AWK-awk} '
BEGIN                                            { v=0; }
($1 == "set_target_properties(libavrdude")       { v=1; }
(v == 1) && /^[[:space:]]+\)/                    { v=0; }
(v == 1) && /^[[:space:]]+VERSION[[:space:]]+/   { version=$2; }
(v == 1) && /^[[:space:]]+SOVERSION[[:space:]]+/ { soversion=$2; }
END                                              { print version;
                                                   print soversion; }
' < "$top_srcdir/CMakeLists.txt")"


# Extract the libavrdude VERSION
CMAKE_LIBAVRDUDE_VERSION="$(printf "%s\n" "$tmp" | { \
  read LIB_VERSION; read LIB_SOVERSION; \
  printf "%s\n" "$LIB_VERSION"; })"

test -n "$CMAKE_LIBAVRDUDE_VERSION" || \
    ret_error "Cannot find library VERSION in library 'CMakeLists.txt'"


# Extract the libavrdude SOVERSION
CMAKE_LIBAVRDUDE_SOVERSION="$(printf "%s\n" "$tmp" | { \
  read LIB_VERSION; read LIB_SOVERSION; \
  printf "%s\n" "$LIB_SOVERSION"; })"

test -n "$CMAKE_LIBAVRDUDE_SOVERSION" || \
    ret_error "Cannot find library SOVERSION in library 'CMakeLists.txt'"


# If GIT_DIR is set, use it. If not, try "$top_srcdir/../.git".
test -n "$GIT_DIR" || { \
    GIT_DIR="$top_srcdir/../.git"; \
    export GIT_DIR; \
}


# If working with a git source tree, determine git information
if test -d "$GIT_DIR" && ${GIT-git} --version > /dev/null 2>&1; then
    GIT_COMMIT_HASH="$(${GIT-git} log -1 --format=%h)" || \
	ret_error "$prog: Cannot run 'git log' for commit hash"
    GIT_COMMIT_DATE="$(${GIT-git} log -1 --format=%cd --date=format:%Y%m%d)" || \
	ret_error "$prog: Error: Cannot run 'git log' for commit date"
    GIT_TAG_HASH="$(${GIT-git} log -1 --tags --format=%h)" || \
	ret_error "$prog: Cannot run 'git log' for tag hash"
    # This must be the same sequence as versioninfo_items in configure.ac
    ret_ok "${PROJECT_VERSION}" \
	   "${CMAKE_LIBAVRDUDE_VERSION}" "${CMAKE_LIBAVRDUDE_SOVERSION}" \
	   "${GIT_COMMIT_DATE}" "${GIT_COMMIT_HASH}" "${GIT_TAG_HASH}"
else # This is a github release tarball or github snapshot tarball
    # Presume this is a release version, because who would build a
    # non-release version from a snapshot tarball?
    ret_ok "${PROJECT_VERSION}" \
	   "${CMAKE_LIBAVRDUDE_VERSION}" "${CMAKE_LIBAVRDUDE_SOVERSION}"
fi


# This code should never be reached.
ret_error "$prog: This code should never be reached."
