#!/usr/bin/env bash
#
# mfconfig init source dest
# mfconfig manual source dest
#
# The MarlinFirmware/Configurations layout could be broken up into branches,
# but this makes management more complicated and requires more commits to
# perform the same operation, so this uses a single branch with subfolders.
#
# init - Initialize the repo with a base commit and changes:
#   - Source will be an 'import' branch containing all current configs.
#   - Create an empty 'BASE' branch from 'init-repo'.
#   - Add Marlin config files, but reset all to defaults.
#   - Commit this so changes will be clear in following commits.
#   - Add changed Marlin config files and commit.
#
# manual - Manually import changes from the Marlin repo
#   - Replace 'default' configs with those from the Marlin repo.
#   - Wait for manual propagation to the rest of the configs.
#   - Run init with the given 'source' and 'dest'
#

REPOHOME="`dirname ~/Projects/Maker/Firmware/.`"
MARLINREPO="$REPOHOME/MarlinFirmware"
CONFIGREPO="$REPOHOME/Configurations"

CEXA=config/examples
CDEF=config/default
BC=Configuration.h
AC=Configuration_adv.h

COMMIT_STEPS=0

#cd "$CONFIGREPO" 2>/dev/null || { echo "Can't find Configurations repo!" ; exit 1; }

ACTION=${1:-init}
IMPORT=${2:-"import-2.1.x"}
EXPORT=${3:-"bugfix-2.1.x"}

echo -n "Doing grhh ... " ; grhh ; echo

if [[ $ACTION == "manual" ]]; then

  #
  # Copy the latest default configs from MarlinFirmware/Marlin
  # or one of the import branches here, then use them to construct
  # a 'BASE' branch with only defaults as a starting point.
  #

  echo "- Updating '$IMPORT' from Marlin..."

  git checkout $IMPORT || exit

  # Reset from the latest complete state
  #git reset --hard bugfix-2.1.x

  cp "$MARLINREPO/Marlin/"Configuration*.h "$CDEF/"
  #git add . && git commit -m "Changes from Marlin ($(date '+%Y-%m-%d %H:%M'))."

  echo "- Fix up the import branch and come back."

  read -p "- Ready to init [y/N] ?" INIT_YES
  echo

  [[ $INIT_YES == 'Y' || $INIT_YES == 'y' ]] || { echo "Done." ; exit ; }

  ACTION='init'
fi

if [[ $ACTION == "init" ]]; then
  #
  # Copy all configs from a source such as MarlinFirmware/Marlin
  # or one of the import branches here, then use them to construct
  # a 'BASE' branch with only defaults as a starting point.
  #

  SED=$(which gsed sed | head -n1)

  echo "- Initializing BASE branch..."

  # Use the import branch as the source
  git checkout $IMPORT || exit

  # Copy to a temporary location
  TEMP=$( mktemp -d ) ; cp -R config $TEMP

  # Strip all #error lines
  IFS=$'\n'; set -f
  for fn in $( find $TEMP/config -type f -name "Configuration.h" ); do
    $SED -i~ -e "20,30{/#error/d}" "$fn"
    rm "$fn~"
  done
  unset IFS; set +f

  # Make sure we're not on the 'BASE' branch...
  git checkout init-repo >/dev/null 2>&1 || exit

  # Create 'BASE' as a copy of 'init-repo' (README, LICENSE, etc.)
  git branch -D BASE 2>/dev/null
  git checkout init-repo -b BASE || exit

  # Copy all config files into place
  echo "- Copying all configs from fresh $IMPORT..."
  cp -R "$TEMP/config" .

  # Delete anything that's not a Configuration file
  find config -type f \! -name "Configuration*" -exec rm "{}" \;

  # DEBUG: Commit the original config files for comparison
  ((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Commit for comparison" >/dev/null

  # Init Cartesian/SCARA/TPARA configurations to default
  echo "- Initializing configs to default state..."

  find "$CEXA" -name $BC -print0 \
    | while read -d $'\0' F ; do cp "$CDEF/$BC" "$F" ; done
  find "$CEXA" -name $AC -print0 \
    | while read -d $'\0' F ; do cp "$CDEF/$AC" "$F" ; done

  # DEBUG: Commit the reset for review
  ((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset configs..." >/dev/null

  # Update the %VERSION% in the README.md file
  VERS=$( echo $EXPORT | $SED 's/release-//' )
  eval "${SED} -E -i~ -e 's/%VERSION%/$VERS/g' README.md"
  rm -f README.md~

  # NOT DEBUGGING: Commit the 'BASE', ready for customizations
  ((COMMIT_STEPS)) || git add . >/dev/null && git commit --amend --no-edit >/dev/null

  # Create a new branch from 'BASE' for the final result
  echo "- Creating '$EXPORT' branch for the result..."
  git branch -D $EXPORT 2>/dev/null
  git checkout -b $EXPORT || exit

  # Delete temporary branch
  git branch -D BASE 2>/dev/null

  echo "- Applying example config customizations..."
  cp -R "$TEMP/config" .
  find config -type f \! -name "Configuration*" -exec rm "{}" \;

  addpathlabels() {
    find config -name "Conf*.h" -print0 | while read -d $'\0' fn ; do
      fldr=$(dirname "$fn")
      blank_line=$(awk '/^\s*$/ {print NR; exit}' "$fn")
      $SED -i~ "${blank_line}i\\\n#define CONFIG_EXAMPLES_DIR \"$fldr\"" "$fn"
      rm -f "$fn~"
    done
  }

  echo "- Adding path labels to all configs..."
  addpathlabels

  git add . >/dev/null && git commit -m "Examples Customizations" >/dev/null

  echo "- Copying extras from Marlin..."
  cp -R "$TEMP/config" .

  # Apply labels again!
  addpathlabels

  git add . >/dev/null && git commit -m "Examples Extras" >/dev/null

  rm -rf $TEMP

  git push -f --set-upstream upstream "$EXPORT"

else

  echo "Usage: mfconfig init|manual|rebase"

fi
