#!/bin/sh
set -e

# The container engine: `podman` (default) or `docker`.
CONTAINER=${CONTAINER:-podman}

main() {
  # Use UTC time for everything.
  export TZ=UTC0
  # Set minimal locale.
  export LC_ALL=C
  # Set source date. This is honored by `asciidoctor` and other tools.
  SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
  export SOURCE_DATE_EPOCH

  case "$CONTAINER" in
  podman)
    # Rootless podman on Linux needs cgroupfs.
    if [ "$(uname)" = Linux ]; then
      engine="podman --cgroup-manager=cgroupfs"
    else
      engine=podman
    fi
    ;;
  docker)
    engine=docker
    # A remote builder, as in Buildkite, only keeps the image in its cache
    # unless asked to load it into Docker.
    load=--load
    ;;
  *)
    echo "fatal: CONTAINER must be podman or docker, not '$CONTAINER'" >&2
    exit 1
    ;;
  esac

  if ! command -v "$CONTAINER" >/dev/null; then
    echo "fatal: $CONTAINER is not installed" >&2
    exit 1
  fi

  if ! command -v sha256sum >/dev/null; then
    echo "fatal: sha256sum is not installed" >&2
    exit 1
  fi

  # Use a fixed length: the default of `--short` depends on the clone.
  rev="$(git rev-parse HEAD | cut -c1-8)"
  tempdir="$(mktemp -d)"
  context="$tempdir/heartwood-$rev"
  version="$("$(dirname "$0")/version")"
  image=radicle-build-$version
  container=radicle-build-container
  rust_version="$(cat "$(dirname "$0")/../../../rust-toolchain")"

  echo "Building Radicle $version.."
  echo "Exporting repository at $rev to $context.."
  # Only explorer/ is part of the build, with paths relative to it. Run from
  # the repository root, since in a subdirectory `git archive` only includes
  # paths under that subdirectory. Pass a directory, not a tarball on stdin, as
  # the build context: podman on macOS fails to copy symlinks from a tarball.
  mkdir "$context"
  git -C "$(git rev-parse --show-toplevel)" archive HEAD:explorer | tar -x -C "$context"

  echo "Building image ($image) with $CONTAINER.."

  # Build on linux/arm64 on every host, so that builds on different hosts
  # give the same bytes. Apple silicon and the Buildkite release queue run it
  # natively; amd64 hosts run it under emulation.
  $engine build $load \
    --build-arg "RUST_VERSION=$rust_version" \
    --build-arg SOURCE_DATE_EPOCH \
    --build-arg TZ \
    --build-arg LC_ALL \
    --build-arg "RADICLE_HTTPD_VERSION=$version" \
    --build-arg "GIT_HEAD=$rev" \
    --platform linux/arm64 --tag "$image" -f "$(dirname "$0")/Dockerfile" "$context"

  echo "Creating container ($container).."
  $engine rm --force "$container" >/dev/null 2>&1 || true
  $engine create --name "$container" "$image" >/dev/null

  # Copy build artifacts to output folder.
  outdir="$(dirname "$0")/artifacts"
  mkdir -p "$outdir"
  # These archives are not from a CI build, see `fetch`.
  rm -f "$outdir/build-url"
  $engine cp "$container:/builds/." "$outdir/"

  for target in $(cat "$(dirname "$0")/TARGETS"); do
    # `radicle-httpd` and `radicle-search` are released together: each ships as
    # its own per-target archive.
    for bin in radicle-httpd radicle-search; do
      filename="$bin-$version-$target.tar.xz"
      filepath="$outdir/$filename"

      # Output SHA256 digest of archive.
      checksum="$(cd "$outdir" && sha256sum "$filename")"
      echo "Checksum of $filepath is $(echo "$checksum" | cut -d' ' -f1)"
      echo "$checksum" >"$filepath.sha256"
      # A signature from an earlier build no longer matches.
      rm -f "$filepath.sig"
    done
  done

  # Remove build artifacts that aren't needed anymore.
  rm -rf "$tempdir"
  $engine rm "$container" >/dev/null
  $engine rmi "$image" >/dev/null || true
}

# Run build.
echo "Running build.."
main "$@"

# Show artifact checksums.
echo
"$(dirname "$0")/checksums"
echo

echo "Build successful."
