#!/bin/sh

set -o errexit
set -o nounset

ROOT="$(git rev-parse --show-toplevel)"
DEPENDENCIES="$ROOT/DEPENDENCIES"
VENDOR="$ROOT/vendor"
PATCHES="$ROOT/patches"

fail() {
  echo "$1" 1>&2
  exit 1
}

log() {
  echo "-- $1" 1>&2
}

# $1 = name
# $2 = url
# $3 = version
# $4 = tmp
vendor() {
  # Cloning
  log "Fetching $2@$3 into $4/$1"
  git clone --recurse-submodules --jobs 8 "$2" "$4/$1"
  git -C "$4/$1" reset --hard "$3"

  # Patching
  if [ -d "$PATCHES/$1" ]
  then
    for patch in "$2"/*.patch
    do
      log "Patching $1: $patch"
      git -C "$4/$1" apply --3way "$patch"
    done
  fi

  # Pruning
  log "Pruning $4/$1"
  git -C "$4/$1" submodule foreach "rm -rf .git"
  git -C "$4/$1" submodule foreach "rm -rf .gitignore"
  git -C "$4/$1" submodule foreach "rm -rf .github"
  git -C "$4/$1" submodule foreach "rm -rf .gitmodules"
  git -C "$4/$1" submodule foreach "rm -rf .gitattributes"
  rm -rf "$4/$1/.git"
  rm -rf "$4/$1/.gitignore"
  rm -rf "$4/$1/.github"
  rm -rf "$4/$1/.gitmodules"
  rm -rf "$4/$1/.gitattributes"

  # Masking
  if [ -f "$VENDOR/$1.mask" ]
  then
    while read -r path
    do
      log "Masking $1: $path"
      rm -rf "$4/$1/${path:?}"
    done < "$VENDOR/$1.mask"
  fi

  # Swap
  log "Moving $4/$1 to $VENDOR/$1"
  rm -rf "$VENDOR/${1:?}"
  mkdir -p "$VENDOR"
  mv "$4/$1" "$VENDOR/$1"
}

if [ ! -f "$DEPENDENCIES" ]
then
  fail "File not found: $DEPENDENCIES"
fi

DEPENDENCY="${1-}"
if [ -n "$DEPENDENCY" ]
then
  LINE="$(grep "^$DEPENDENCY " < "$DEPENDENCIES" || true)"
  if [ -z "$LINE" ]
  then
    fail "Unknown dependency: $DEPENDENCY"
  fi
  NAME="$(echo "$LINE" | cut -d ' ' -f 1)"
  URL="$(echo "$LINE" | cut -d ' ' -f 2)"
  VERSION="$(echo "$LINE" | cut -d ' ' -f 3)"
  if [ -z "$NAME" ] || [ -z "$URL" ] || [ -z "$VERSION" ]
  then
    fail "Invalid dependency definition: $DEPENDENCY"
  fi

  TMP="$(mktemp -d -t vendorpull-clone-XXXXX)"
  log "Setting up temporary directory at $TMP..."
  clean() { rm -rf "$TMP"; }
  trap clean EXIT

  vendor "$NAME" "$URL" "$VERSION" "$TMP"
else
  TMP="$(mktemp -d -t vendorpull-clone-XXXXX)"
  log "Setting up temporary directory at $TMP..."
  clean() { rm -rf "$TMP"; }
  trap clean EXIT

  while read -r line
  do
    NAME="$(echo "$line" | cut -d ' ' -f 1)"
    URL="$(echo "$line" | cut -d ' ' -f 2)"
    VERSION="$(echo "$line" | cut -d ' ' -f 3)"
    if [ -z "$NAME" ] || [ -z "$URL" ] || [ -z "$VERSION" ]
    then
      fail "Invalid dependency definition"
    fi

    vendor "$NAME" "$URL" "$VERSION" "$TMP"
  done < "$DEPENDENCIES"
fi
