#!/bin/bash

# Script to package all git changes and untracked files into a single archive
#
# ./package_repo_changes [ARCHIVE_NAME]

set -euo pipefail

cleanup() {
    local exit_code=$?
    echo "Cleaning up temporary files..."
    [[ -d "${TEMP_DIR:-}" ]] && rm -rf "$TEMP_DIR"
    exit $exit_code
}

trap cleanup EXIT

# Get the repository root directory
REPO_DIR=$(git rev-parse --show-toplevel)
cd "$REPO_DIR"

TEMP_DIR=$(mktemp -d)
echo "Creating temporary directory: $TEMP_DIR"

# Check if there are any changes to package
if git diff --quiet && [[ -z "$(git ls-files --others --exclude-standard)" ]]; then
    echo "No changes detected in the repository. Nothing to package."
    exit 0
fi

echo "Generating patch file for tracked changes..."
git diff >"$TEMP_DIR/changes.patch"

# Include staged changes as well
if ! git diff --staged --quiet; then
    echo "Including staged changes..."
    git diff --staged >>"$TEMP_DIR/changes.patch"
fi

echo "Packaging untracked files..."
git ls-files --others --exclude-standard >"$TEMP_DIR/untracked_files.txt"

if [[ -s "$TEMP_DIR/untracked_files.txt" ]]; then
    COPYFILE_DISABLE=1 tar -czf "$TEMP_DIR/untracked.tar.gz" -T "$TEMP_DIR/untracked_files.txt"
    echo "Untracked files packaged successfully."
else
    echo "No untracked files found."
    touch "$TEMP_DIR/untracked.tar.gz"
fi

# Allow custom archive name with default fallback
ARCHIVE_NAME=${1:-"changes_$(date +%Y%m%d_%H%M%S).tar.gz"}
echo "Creating final archive: $ARCHIVE_NAME"
COPYFILE_DISABLE=1 tar -czf "$ARCHIVE_NAME" -C "$TEMP_DIR" changes.patch untracked.tar.gz

echo "Archive created successfully at: $REPO_DIR/$ARCHIVE_NAME"
echo ""
echo "To apply these changes elsewhere:"
echo "1. Extract the archive: tar -xzf $ARCHIVE_NAME"
echo "2. Apply the patch: git apply changes.patch"
echo "3. Extract untracked files: tar -xzf untracked.tar.gz"
