#!/bin/sh

# shellcheck source=../lib/load-configuration
. "${0%/*}/../lib/load-configuration"

# shellcheck disable=SC2016
usage() {
  >&2 echo ''
  >&2 echo 'check-upstrea-bug-tracker: check archlinux'"'"' bug tracker'
  >&2 echo 'for open bugs on packages that fail to build'
  >&2 echo ''
  >&2 echo 'possible options:'
  >&2 echo '  -a|--architecture $arch:'
  >&2 echo '    only check packages which fail on $arch'
  >&2 echo '  -f|--failure $identifier:'
  >&2 echo '    only check packages which fail due to $identifier'
  >&2 echo '  -p|--package $package:'
  >&2 echo '    only check package $package (can be given multiple times)'
  >&2 echo '  -h|--help:    Show this help and exit.'
  [ -z "$1" ] && exit 1 || exit "$1"
}

eval set -- "$(
  getopt -o a:f:p:h \
    --long architecture: \
    --long failure: \
    --long package: \
    --long help \
    -n "$(basename "$0")" -- "$@" || \
  echo usage
)"
architecture=''
identifier=''
packages=''

while true
do
  case "$1" in
    -a|--architecture)
      shift
      if [ -n "${architecture}" ]; then
        >&2 echo 'Option -a only allowed once.'
        usage
      fi
      architecture="$1"
    ;;
    -f|--failure)
      shift
      if [ -n "${identifier}" ]; then
        >&2 echo 'Option -f only allowed once.'
        usage
      fi
      identifier="$1"
    ;;
    -p|--package)
      shift
      packages="$packages $1"
    ;;
    -h|--help)
      usage 0
    ;;
    --)
      shift
      break
    ;;
    *)
      >&2 echo 'Whoops, forgot to implement option "'"$1"'" internally.'
      exit 42
    ;;
  esac
  shift
done

if [ $# -ne 0 ]; then
  >&2 echo 'Too many arguments.'
  usage
fi

tmp_dir=$(mktemp -d 'tmp.check-upstream-bug-tracker.XXXXXXXXXX' --tmpdir)
trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT

>&2 printf 'receiving upstream bugs of broken packages '

# shellcheck disable=SC2016
{
  printf 'SELECT DISTINCT'
  printf '`package_sources`.`%s`,' \
    'pkgbase' \
    'git_revision' \
    'mod_git_revision'
  printf '`upstream_repositories`.`name`'
  printf ' FROM `package_sources`'
  mysql_join_package_sources_upstream_repositories
  mysql_join_package_sources_build_assignments
  if [ -n "${architecture}" ]; then
    mysql_join_build_assignments_architectures
    printf ' AND `architectures`.`name`=from_base64("%s")' \
      "$(
        printf '%s' "${architecture}" | \
          base64 -w0
      )"
  fi
  if [ -n "${identifier}" ]; then
    mysql_join_build_assignments_failed_builds
    mysql_join_failed_builds_fail_reasons
    printf ' AND `fail_reasons`.`name`=from_base64("%s")' \
      "$(
        printf '%s' "${identifier}" | \
          base64 -w0
      )"
  fi
  mysql_join_build_assignments_binary_packages
  mysql_join_binary_packages_binary_packages_in_repositories
  printf ' WHERE `binary_packages_in_repositories`.`repository`=%s' \
    "${repository_ids__any_build_list}"
  printf ' AND `build_assignments`.`is_broken`'
  printf ' AND `build_assignments`.`is_blocked` IS NULL;\n'
} | \
mysql_run_query 'unimportant' \
> "${tmp_dir}/broken-packages-candidates"

# explicit package list overwrites select broken packages from database
if [ -n "${packages}" ]; then
  >&2 echo '.. using only explicit packages given'
  for p in $packages; do
    grep "$p" "${tmp_dir}/broken-packages-candidates" >> "${tmp_dir}/filtered-broken-packages-candidates"
  done
  mv "${tmp_dir}/filtered-broken-packages-candidates" "${tmp_dir}/broken-packages-candidates"
fi

while read -r pkgbase git_revision mod_git_revision repository; do
  >&2 printf '.'
  curl -Ssg 'https://bugs.archlinux.org/index.php?string=['"${pkgbase}"']&status[]=open' | \
    sed -n '
      s@^.*<td class='"'"'task_id'"'"'><a href="https://bugs\.archlinux\.org/task/\([0-9]\+\)?.*<td class='"'"'task_summary'"'"'><a href=[^>]\+>\(.*\)</a></td>.*$@\1\t\2@
      T
      s/^/'"${pkgbase}.${git_revision}.${mod_git_revision}.${repository}"'\t/
      p
    '
done > \
"${tmp_dir}/broken-packages" \
< "${tmp_dir}/broken-packages-candidates"

>&2 printf ' done\n'

while [ -s "${tmp_dir}/broken-packages" ]; do
  identifier=$(
    head -n1 "${tmp_dir}/broken-packages" | \
      cut -f1
  )
  fs_ids=''
  OIFS="${IFS}"
  lines=$(
    grep "^$(str_to_regex "${identifier}")\\s" "${tmp_dir}/broken-packages" | \
      cut -f2,3 | \
      tr '\t\n' '\n\t'
  )
  IFS=$(printf '\t')
  # shellcheck disable=SC2013
  for line in ${lines}; do
    IFS="${OIFS}"
    printf '> '
    printf '%s' "${line}" | \
      tr '\t\n' '\n\t' | \
      cut -f2
    printf 'Should we wait (empty = "yes")? '
    read -r w
    if [ -z "${w}" ]; then
      fs_ids="${fs_ids},FS#$(
        printf '%s\n' "${line}" | \
          tr '\t\n' '\n\t' | \
          cut -f1
      )"
    fi
  done
  IFS="${OIFS}"
  if [ -n "${fs_ids}" ]; then
    printf '%s.any wait for %s\n' \
      "${identifier}" \
      "${fs_ids#,}" >> \
      "${tmp_dir}/block-list"
  fi
  sed -i '/^'"$(str_to_regex "${identifier}")"'\s/d' "${tmp_dir}/broken-packages"
done

if [ -s "${tmp_dir}/block-list" ]; then
  "${base_dir}/bin/modify-package-state" -w -b "${tmp_dir}/block-list"
fi