#!/usr/bin/env bash

set -e
set -u
set -o pipefail

esyCommandHelp() {
  cat <<EOF
usage: esy import-build <path-to-build>
       esy import-build -f/--from <file-with-path-list>

This command imports the build from <path-to-build> into the global store.
The build can be either a directory or a tar.gz archive.

Alternatively -f/--from option could be supplied with the file with a list
builds to import, one path per line.

EOF
}

BINDIR=$(dirname "$0")

# shellcheck source=./realpath.sh
source "$BINDIR/realpath.sh"
# shellcheck source=./esyConfig.sh
source "$BINDIR/esyConfig.sh"
# shellcheck source=./esyRuntime.sh
source "$BINDIR/esyRuntime.sh"

stageDir=$(mktemp -d)
destStorePath=$(esyGetStorePathFromPrefix "$ESY__PREFIX")
destStorePathLen=$(esyStrLen "$destStorePath")

function esyImportBuild () {
  set -e
  set -u
  set -o pipefail

  local buildPath
  local buildId
  local stageBuildPath
  local origStorePath

  buildPath="$1"
  buildId=$(basename "${buildPath%.tar.gz}")

  stageBuildPath="$stageDir/$buildId"

  echo "$buildId: importing..."

  if [ -d "$destStorePath/i/$buildId" ]; then
    echo "$buildId: already exists in store, skipping..."
    exit 0
  fi

  if [[ "$buildPath" == *.tar.gz ]]; then
    cp "$buildPath" "$stageBuildPath.tar.gz"
    (cd "$stageDir" && tar xzf "$stageBuildPath.tar.gz")
  else
    # copy into stage recursively (-R) and do not follow symlinks (-P)
    cp -RP "$buildPath" "$stageBuildPath"
  fi

  origStorePath=$(cat "$stageBuildPath/_esy/storePrefix")
  origStorePathLen=$(esyStrLen "$origStorePath")

  if [ "$origStorePathLen" -ne "$destStorePathLen" ]; then
    echo "error: unable to import build: store path length mismatch"
    exit 1
  fi

  esyRewriteStorePrefix "$stageBuildPath" "$origStorePath" "$destStorePath"

  mkdir -p "$destStorePath/i"
  mv "$stageBuildPath" "$destStorePath/i"

  echo "$buildId: done"
}

if [ "$1" == "--from" ] || [ "$1" == "-f" ]; then
  shift

  if [ -z "${1+present}" ]; then
    echo "error: provide value for --from/-f option"
    exit 1
  fi

  buildPathList="$1"

  # Export b/c we spawn bash in xargs
  export BINDIR
  export stageDir
  export destStorePath
  export destStorePathLen
  export -f esyImportBuild
  export -f esyStrLen
  export -f esyRewriteStorePrefix
  export -f esyRewriteSymlink

  set +e
  cat "$buildPathList" | xargs -n1 -P12 -I {} bash -c 'esyImportBuild "{}"'
  ret="$?"
  set -e
else
  buildPath="$1"
  set +e
  (esyImportBuild "$buildPath")
  ret="$?"
  set -e
fi

rm -rf "$stageDir"

if [ $ret -ne 0 ]; then
  exit 1
fi
