#!/usr/bin/env bash

function is-installed() {
  type "${1}"
}

function start-docker() {
  is-installed "systemctl" || return $?
  is-installed "docker" || return $?

  res="$(systemctl show --property ActiveState docker)" || return $?
  case "${res}" in
    "ActiveState=active")
      # Docker service is active
      true
      ;;
    "ActiveState=inactive")
      # Docker service is inactive -> Let's start it
      echo "Starting docker service ..."
      sudo systemctl start docker || return $?
      sleep 5s || return $?
      ;;
    *)
      echo "Unknown state or error! This can happen after kernel upgrade without restart."
      return 1
  esac
}

function update-build-image() {
  # "--no-cache" to always run the "pacman -Syu" build step
  sudo docker-compose build --pull --no-cache
}

function build-pkg() {
  # $1: package-name
  # $2, $3, ...: makepkg-args

  # --rm: Remove container after run.
  COMPOSE_ARGS=('run' '--rm' 'makepkg' "${1}") || return $?

  if [ ${#MAKEPKG_ARGS[@]} -gt 0 ]; then
    COMPOSE_ARGS+=("${MAKEPKG_ARGS[@]}") || return $?
  fi

  sudo docker-compose "${COMPOSE_ARGS[@]}" || return $?
}

function push-pkg() {
  arch-repo-push-new || return $?  # Push remote repository
}

function build-and-push() {
  for PKG in "$@"; do
    build-pkg "${PKG}" || return $?
  done
  push-pkg || return $?
}

function space_separated_to_array() {
  # arg $1: name of variable with space separated list
  # arg $2: name of array to store values into

  local -n ptr=$1  || return $?
  local -n ptr2=$2 || return $?
  # ptr space separated list.
  # Store this as array ptr2.
  # Without newline at last array element: https://unix.stackexchange.com/a/519917/315162
  # shellcheck disable=SC2034
  readarray -d " " -t ptr2 < <(printf '%s' "$ptr")
}

function usage() {
  echo "Usage:
  ${0} <PKGLIST-FILE> [-- <makepkgArguments>]
  ${0} -- <makepkgArguments>
With PKGLIST-FILE a file containing zero or more package names in each line, separated by space.
All packages in a line will be built sequentially and are then synced to the remote repository
before continuing with the next line.";
  exit 1;
}

function main() {

  # parse arguments
  {
    if [ "${1}" == '-h' ] || [ "${1}" == '--help' ] ; then
      usage
    fi

    if [ "${1}" == '--' ]; then
      shift; # remove first arg
    else
      # If $1 not set or null, use 'pkglist.tmp'.
      PKGLIST="${1:-pkglist.tmp}"

      if [ $# -gt 1 ]; then
        if [ "${2}" == '--' ]; then
          shift; # remove first arg
          shift; # remove second arg
        else
          usage
        fi
      fi
    fi

    MAKEPKG_ARGS=("$@")
  }

  # check dependencies and start services
  {
    start-docker || return $?
    is-installed "docker-compose" || return $?
  }

  # Read content of PKGLIST file to an array
  # For each line: build and push all space separated packages
  mapfile -t STAGES < "${PKGLIST}"
  # shellcheck disable=SC2034
  for line in "${STAGES[@]}"; do
    # trim leading/tailing whitespaces
    line="$(echo "${line}" | xargs)" || return $?
    space_separated_to_array line pkgs

    # skip empty lines
    # shellcheck disable=SC2154
    if [ "${#pkgs[@]}" -eq 0 ]; then
      echo "Skipped empty line."
      continue;
    fi

    # Rebuild the docker image with refreshed mirrors => this fetches packages that were built in a previous build stage
    update-build-image || return $?
    build-and-push "${pkgs[@]}" || exit $?
  done

  echo "Successfully built all packages!"
}

main "$@"