#!/usr/bin/env bash
set -euo pipefail

PROGRAM=$0
CURRENT_FILENAME=""
DESTINATION_FILENAME=""

function usage()
{
    echo 1>&2 "USAGE: ${PROGRAM} CURRENT_FILENAME DESTINATION_FILENAME"
}

while [[ $# -gt 0 ]]
do
  key="$1"

  if [[ "$CURRENT_FILENAME" == "" ]]; then
      CURRENT_FILENAME=$key
  elif [[ "$DESTINATION_FILENAME" == "" ]]; then
      DESTINATION_FILENAME=$key
  else
      usage
      exit 30  # Error during arguments parsing
  fi
  shift  # past argument or value
done

if [[ "$DESTINATION_FILENAME" == "" ]]; then
    usage
    exit 20  # Missing arguments CURRENT_FILENAME
elif [[ "$CURRENT_FILENAME" == "" ]]; then
    usage
    exit 10  # Missing arguments CURRENT_FILENAME
else
    if [ -e "$DESTINATION_FILENAME"  ]; then
        echo 1>&2 "$DESTINATION_FILENAME already exists."
        echo 1>&2 "Make sure to remove the destination first."
        exit 40
    fi

    if [[ "$DESTINATION_FILENAME" == */ ]]; then
      echo 1>&2 "$DESTINATION_FILENAME is not a file path."
      exit 80
    fi
    if [[ "$DESTINATION_FILENAME" == */* ]]; then
      DESTINATION_DIR="${DESTINATION_FILENAME%/*}"
      if ! mkdir -p "$DESTINATION_DIR"; then
        echo 1>&2 "Failed to create destination directory: $DESTINATION_DIR"
        exit 160
      fi
    fi

    MERGE_OPT=
    ff=$(git config --get merge.ff || true)
    if [[ "$ff" == "only" ]]; then
        MERGE_OPT="--ff"
    fi

    echo "Copying $CURRENT_FILENAME into $DESTINATION_FILENAME"

    INTERMEDIATE_FILENAME="${CURRENT_FILENAME//\//__}-move-to-${DESTINATION_FILENAME//\//__}"

    # We keep the existing file on the side in a commit
    git mv "${CURRENT_FILENAME}" "${INTERMEDIATE_FILENAME}"
    git commit -nm "Keep $CURRENT_FILENAME"

    # We come back to the previous state and revert that change
    INTERMEDIATE_SAVED=$(git rev-parse HEAD)
    git reset --hard HEAD^

    # We move the file to its new destination
    git mv "${CURRENT_FILENAME}" "${DESTINATION_FILENAME}"
    git commit -nm "Copy $CURRENT_FILENAME into $DESTINATION_FILENAME"

    # We come back to the previous state and revert that change again
    DESTINATION_SAVED=$(git rev-parse HEAD)
    git reset --hard HEAD^

    # We keep both files
    # shellcheck disable=SC2086
    git merge $MERGE_OPT "${DESTINATION_SAVED}" "${INTERMEDIATE_SAVED}" -m "Duplicate ${CURRENT_FILENAME} history."

    # We get back our original name
    git mv "${INTERMEDIATE_FILENAME}" "${CURRENT_FILENAME}"
    git commit -nm "Set back ${CURRENT_FILENAME} file"
fi
