#!/bin/bash

export LC_ALL="C"
set -e # Exit when an error is encountered

function help
{
printf '$1: name of the board ( present in archive name )\n'
printf '$2: path of the directory that contains sources\n'
printf '$3: path of a file listing all files to package in $2\n'
printf '$4: path of the directory that contains headers\n'
printf '$5: path of a file listing all files to package in $4\n'
printf '$6: directory where to put resulting archive\n'
printf '$7: path of the directory that contains customer sources\n'
printf '$8: path of a file listing all extra source files => If you use this option be aware that you will have to be on same level as addidata path driver\n'
}
if [ $# -lt  6 ]
then
    printf "Bad number of parameter\n"
    help
    exit 1
fi

BOARD_NAME=$1
SOURCE_DIR=$2
SRC_FILE_LIST=$3
HEADER_DIR=$4
HEADER_FILE_LIST=$5
ARCHIVE_DIR=$6
CUSTOMER_SOURCE_DIR=$7
EXTRA_SOURCE_FILES_LIST=$8 # ONLY PATH from same level as "addidata" path driver (because we will copy with parents directory to keep same hierarchy)

README_PATH=$(git rev-parse --show-toplevel)/README.md
GIT_SCRIPTS_DIR=$(git rev-parse --show-toplevel)/scripts

# get revision hash or tag
# Try to get the git tag first, if available
GIT_TAG=$(git describe --tags --exact-match HEAD 2>/dev/null) || echo "No git tag"
if [ -n "$GIT_TAG" ]; then
    # Use the tag (keep the 'v' prefix for now, we'll handle it in naming)
    SOURCE_DIR_REVISION=$GIT_TAG
    printf "\nGit tag found: $SOURCE_DIR_REVISION \n"

    # Extract version components from tag (format: vYYYY.MM.PATCH)
    TAG_NO_V=${GIT_TAG#v}
    VERSION_MAJOR=$(echo "$TAG_NO_V" | cut -d. -f1)
    VERSION_MINOR=$(echo "$TAG_NO_V" | cut -d. -f2)
    VERSION_PATCH=$(echo "$TAG_NO_V" | cut -d. -f3)

    if [ -z "$VERSION_MAJOR" ] || [ -z "$VERSION_MINOR" ] || [ -z "$VERSION_PATCH" ]; then
        printf "ERROR: Could not parse version from tag $GIT_TAG\n"
        exit 1
    fi
    printf "Extracted version: MAJOR=$VERSION_MAJOR MINOR=$VERSION_MINOR PATCH=$VERSION_PATCH\n"
else
    # Fall back to commit hash
    SOURCE_DIR_REVISION=$(git rev-parse --short HEAD)
    if [ -z "$SOURCE_DIR_REVISION" ]; then printf "Cannot get the git revision\n"; fi
    printf "\nRevision of source directory is $SOURCE_DIR_REVISION \n"
    VERSION_MAJOR=""
    VERSION_MINOR=""
    VERSION_PATCH=""
fi

# get files to package
LIST_OF_SOURCE=`cat $SRC_FILE_LIST`
LIST_OF_SOURCE+=" "

if [ -n "$CUSTOMER_SOURCE_DIR" ]; then
	TMP_LIST_OF_SOURCE=`cat $CUSTOMER_SOURCE_DIR/$SRC_FILE_LIST`
	printf "TMP_LIST_OF_SOURCE : $TMP_LIST_OF_SOURCE\n"
	printf "Set customer source files directory\n"
	for FF in $TMP_LIST_OF_SOURCE
	do
		LIST_OF_SOURCE+=" $CUSTOMER_SOURCE_DIR/$FF"
	done
fi

LIST_OF_HEADER=`cat $HEADER_FILE_LIST`

# create temporary directory
TMP_DIR=`mktemp -d`
printf "created temporary directory $TMP_DIR\n"

# Use tag if available, otherwise use git+commit_hash
if [ -n "$GIT_TAG" ]; then
    # For tagged releases, use the tag name (with v prefix)
    PKGGEN_DIR="$TMP_DIR/${BOARD_NAME}_${SOURCE_DIR_REVISION}"
else
    # For untagged builds, use the old git+hash format
    PKGGEN_DIR="$TMP_DIR/${BOARD_NAME}_git+${SOURCE_DIR_REVISION}"
fi

SCRIPT_DIR=$PKGGEN_DIR/scripts
BASE_SOURCE_DIR=$PKGGEN_DIR/drivers/addidata
mkdir -p $BASE_SOURCE_DIR
mkdir -p $SCRIPT_DIR

FINAL_SOURCE_DIR=$BASE_SOURCE_DIR/$BOARD_NAME
printf "Creating directory $FINAL_SOURCE_DIR\n"
mkdir $FINAL_SOURCE_DIR

# Common additional .mk file (for RedHat distributions)
if [ -e ../redhat.mk ]
then
  cp -a ../redhat.mk $BASE_SOURCE_DIR
fi

# If the header file list is empty, don't generate things for the header
if [ ${#LIST_OF_HEADER} != 0 ]
then
    FINAL_HEADER_DIR=$PKGGEN_DIR/include/linux/addidata
    printf "\nCreating directory $FINAL_HEADER_DIR"
    mkdir -p $FINAL_HEADER_DIR
fi

if [ "$CUSTOMER_SOURCE_DIR" != "" ];
then
    printf "\nCreating directory $FINAL_SOURCE_DIR/$CUSTOMER_SOURCE_DIR\n"
    mkdir -p "$FINAL_SOURCE_DIR/$CUSTOMER_SOURCE_DIR"
fi

cp -v $README_PATH $PKGGEN_DIR
# Replace 'apci1500' with $BOARD_NAME in the copied README.md
sed -i.bak "s/apci1500/$BOARD_NAME/g" $PKGGEN_DIR/README.md
rm -f $PKGGEN_DIR/README.md.bak

cp -rv $GIT_SCRIPTS_DIR/* $SCRIPT_DIR

printf "\nCopying source files"
for FF in $LIST_OF_SOURCE
do
    printf "$SOURCE_DIR/$FF -> $FINAL_SOURCE_DIR/$FF\n"
    cp -R $SOURCE_DIR/$FF $FINAL_SOURCE_DIR/$FF
done

# If the header file list is empty, don't generate things for the header
if [ ${#LIST_OF_HEADER} != 0 ]
then
    printf "\nCopying header files\n"
    for FF in $LIST_OF_HEADER
    do
        printf "$SOURCE_DIR/$FF -> $FINAL_SOURCE_DIR/$FF\n"

        # If we have a tag and this is a board-specific header (apciXXXX.h), add version defines
        if [ -n "$GIT_TAG" ] && [[ "$FF" =~ [ax]pcie?[0-9]{1,4}([Xx]{3,4})?.h ]] && [ -n "$VERSION_MAJOR" ] && [ -n "$VERSION_MINOR" ] && [ -n "$VERSION_PATCH" ]; then
            # Extract the board name from the header filename (e.g., apci1516.h -> APCI1516)
            HEADER_BASENAME=$(basename "$FF" .h)
            HEADER_UPPER=$(echo "$HEADER_BASENAME" | tr '[:lower:]' '[:upper:]')

            # Create a temporary copy of the header
            TEMP_HEADER="$TMP_DIR/temp_$FF"
            cp "$HEADER_DIR/$FF" "$TEMP_HEADER"

            # Add or update the version defines
            # First, remove any existing version defines for this board
            sed -i "/^#define ${HEADER_UPPER}_DRIVER_VERSION_MAJOR/d" "$TEMP_HEADER"
            sed -i "/^#define ${HEADER_UPPER}_DRIVER_VERSION_MINOR/d" "$TEMP_HEADER"
            sed -i "/^#define ${HEADER_UPPER}_DRIVER_VERSION_PATCH/d" "$TEMP_HEADER"

            # Insert the version defines before the final #endif (any format)
            # Match any #endif line (with or without comment) and insert before it
            sed -i "s|^#include\ <apci.h>|#define ${HEADER_UPPER}_DRIVER_VERSION_MAJOR ${VERSION_MAJOR}\n#define ${HEADER_UPPER}_DRIVER_VERSION_MINOR ${VERSION_MINOR}\n#define ${HEADER_UPPER}_DRIVER_VERSION_PATCH ${VERSION_PATCH}\n\n&|" "$TEMP_HEADER"

            cp -R "$TEMP_HEADER" "$FINAL_HEADER_DIR/$FF"
            rm -f "$TEMP_HEADER"
            printf "  Added version defines to $FF: MAJOR=$VERSION_MAJOR MINOR=$VERSION_MINOR PATCH=$VERSION_PATCH\n"
        else
            cp -R $HEADER_DIR/$FF $FINAL_HEADER_DIR/$FF
        fi
    done
fi

if [ "$EXTRA_SOURCE_FILES_LIST" != "" ];
then
    # Copy extra source files
    LIST_OF_EXTRA_SOURCE_FILES=`cat $EXTRA_SOURCE_FILES_LIST`

    # If the extra source file list is empty, don't generate things
    if [ ${#LIST_OF_EXTRA_SOURCE_FILES} != 0 ]
    then
        printf "\nCopying extra source files"
        cd ..
        for FF in $LIST_OF_EXTRA_SOURCE_FILES
        do
            printf "$FF -> $BASE_SOURCE_DIR/$FF"
            cp --parents $FF $BASE_SOURCE_DIR
        done
    fi
fi

# Determine archive name based on whether we have a tag or commit hash
if [ -n "$GIT_TAG" ]; then
    # For tagged releases, use the tag in the archive name
    BASE_ARCHIVE_NAME="${BOARD_NAME}_${GIT_TAG}"
else
    # For untagged builds, use the old git+hash format
    BASE_ARCHIVE_NAME="${BOARD_NAME}_git+${SOURCE_DIR_REVISION}"
fi

ARCHIVE_NAME="/tmp/${BASE_ARCHIVE_NAME}.tar.bz2"

printf "\nGenerating archive $ARCHIVE_NAME"

cd $PKGGEN_DIR

OLDDIR=$PWD
cd $PKGGEN_DIR/../ && tar jcvf "$ARCHIVE_NAME" "$(basename $PKGGEN_DIR)"

printf "\n"

EXPECTED_ARCHIVE="$ARCHIVE_DIR/${BASE_ARCHIVE_NAME}.tar.bz2"
if [ "$ARCHIVE_NAME" != "$EXPECTED_ARCHIVE" ]
then
    printf "Copying archive $ARCHIVE_NAME to directory $ARCHIVE_DIR\n"
    mv -f "$ARCHIVE_NAME" "$ARCHIVE_DIR"
    if [ $? != 0 ] ; then exit 1 ; fi
else
    printf "Created archive $ARCHIVE_NAME"
fi

cd $OLDDIR

printf "\nNow, remove temporary directory $TMP_DIR"
rm -rf $TMP_DIR
