#!/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.
#
# -----------------------------------------------------------------------------
# getversion — determine the project version for packaging and diagnostics
# -----------------------------------------------------------------------------
#
# This script computes a version string using the following logic:
#
#   1. Extract the base PACKAGE_VERSION from the `configure` script.
#
#   2. If running inside a Git repository and `git describe` is usable:
#
#      a. If the current commit matches an annotated tag exactly:
#           VERSION = <tag>
#         e.g.,     VERSION = 2.0.0+RC1
#
#      b. If the current commit is ahead of a tag:
#           VERSION = <PACKAGE_VERSION>+dev.<N>.g<commit>
#         e.g.,     VERSION = 2.0.1-devel+dev.3.gabcd123
#
#   3. If *not* in a Git repo but a `VERSION` file exists:
#
#      a. If the file contains a line like "<version> build <build_number>", both values are extracted.
#
#      b. Otherwise, the VERSION is read from the file and the BUILDNUMBER is taken from BUILD_NUMBER if it exists.
#
#      (This is the case for Apache Cloudberry packaging builds, where these files are created by the
#       release script and may also be leveraged by downstream users.)
#
#   4. If neither a Git repo nor a VERSION file is present:
#         VERSION = <PACKAGE_VERSION> from configure
#         BUILDNUMBER = dev
#
#   5. If a BUILD_NUMBER file is present and BUILDNUMBER is "dev", it will override the default:
#         BUILDNUMBER = $(cat BUILD_NUMBER)
#
# Output:
#   - Default: <version> build <build_number>
#   - With --short: just <version>
#
# Examples:
#   ./getversion
#       → 2.0.1-devel+dev.3.gabcd123 build dev
#
#   ./getversion --short
#       → 2.0.1-devel+dev.3.gabcd123
#
#   (On exact tag)
#       → 2.0.0+RC1 build dev
#
# Supported Features:
#   - Handles annotated tags with special characters like `+` or `-`
#   - Produces semver-compatible version strings for CI/CD
#   - Works with or without Git
#
# Intended for use in:
#   - Release packaging
#   - Diagnostic reporting
#   - Embedding traceable version info into builds
#
# ======================================================================

# Make sure we're running from the root git repository
pushd "$(dirname "$0")" > /dev/null

# Extract PACKAGE_VERSION from the configure script
VERSION=$(perl -ne 'print $1 if /^PACKAGE_VERSION='\''(.+)'\''$/' < configure)
BUILDNUMBER=dev

# Function to generate a dev suffix like "dev.1.gabcd123"
generate_dev_version() {
    local latest_tag
    latest_tag=$(git describe --tags --abbrev=0)
    local full_desc
    full_desc=$(git describe --tags --long)
    local suffix="${full_desc#$latest_tag-}"
    echo "dev.${suffix//-/.}"
}

# Check if we're in a Git repo and git is available
if type git >/dev/null 2>&1 && [ -d '.git' ]; then
    # Ensure git describe doesn't fail due to shallow clone
    if git describe --tags --long >/dev/null 2>&1; then
        if git describe --exact-match >/dev/null 2>&1; then
            # We're exactly on a tag
            VERSION=$(git describe --exact-match)
        else
            # Not on a tag: add dev version suffix
            VERSION+="+$(generate_dev_version)"
        fi
    fi
# Not a git repo but VERSION file exists
elif [[ -s ./VERSION ]]; then
    # Support both legacy "<version> build <build_number>" and newer single-version formats
    if grep -q ' build ' ./VERSION; then
        VERSION=$(awk -F' build ' '{print $1}' ./VERSION)
        BUILDNUMBER=$(awk -F' build ' '{print $2}' ./VERSION)
    else
        VERSION=$(<./VERSION)
        if [[ -f ./BUILD_NUMBER ]]; then
            BUILDNUMBER=$(<./BUILD_NUMBER)
        fi
    fi
fi

# Handle optional flag
FLAG="${1:-noflag}"
if [ "$FLAG" = "--short" ]; then
    echo "${VERSION}"
else
    if [[ ${BUILDNUMBER} = "dev" && -f BUILD_NUMBER ]]; then
        BUILDNUMBER=$(<BUILD_NUMBER)
    fi
    echo "${VERSION} build ${BUILDNUMBER}"
fi

popd > /dev/null
