#!/bin/sh

# shellcheck source=conf/default.conf
. "${0%/*}/../conf/default.conf"

# TODO: save information in database

# TODO: read information from database

if [ -s "${work_dir}/build-master-sanity" ]; then
  >&2 echo 'Build master is not sane.'
  exit
fi

tmp_dir=$(mktemp -d 'tmp.calculate-dependent-packages.XXXXXXXXXX' --tmpdir)
trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT

sort -k1,1 -u "${work_dir}/build-list" > \
  "${tmp_dir}/build-list"

while read -r pkg rev mod_rev repo; do
  generate_package_metadata "${pkg}" "${rev}" "${mod_rev}" "${repo}"
done < \
  "${tmp_dir}/build-list"

mkdir "${tmp_dir}/loops"
find "${work_dir}/build-list.loops" -maxdepth 1 -regextype grep \
  -regex '.*/loop_[0-9]\+' | \
  while read -r loop; do
    sort -u "${loop}" | \
      join -j 1 - "${tmp_dir}/build-list" | \
      tr ' ' '.' > \
      "${tmp_dir}/loops/${loop##*/}"
  done

touch "${tmp_dir}/dependent-count"

tr ' ' '.' < \
  "${tmp_dir}/build-list" | \
  sponge "${tmp_dir}/build-list"

sums=''

while [ -s "${tmp_dir}/build-list" ] && [ "${sums}" != "$(sha512sum "${tmp_dir}/dependent-count")" ]; do

  sums=$(
    sha512sum "${tmp_dir}/dependent-count"
  )

  {
    sed 's|^|? |' "${tmp_dir}/build-list"
    sed 'p' "${tmp_dir}/dependent-count"
  } | \
    sort -k2,2 | \
    uniq -uf1 | \
    cut -d' ' -f2 | \
    sponge "${tmp_dir}/build-list"

  sed '
    s|^|'"${work_dir}"'/package-infos/|
    s|$|.build-depends|
  ' "${tmp_dir}/build-list" | \
    xargs -r grep -hvx 'base\|base-devel' | \
    sort -u > \
    "${tmp_dir}/build-list.build-depends"

  sed '
    s|^\S\+ |'"${work_dir}"'/package-infos/|
    s|$|.build-depends|
  ' "${tmp_dir}/dependent-count" | \
    xargs -r grep -Hvx 'base\|base-devel' | \
    sed '
      s|^.*/||
      s|\.build-depends:| |
    ' | \
    sort -k2,2 > \
    "${tmp_dir}/dependent-count.build-depends"

  rm -f "${tmp_dir}/dependent-count.new"
  touch "${tmp_dir}/dependent-count.new"

  while read -r sf; do
    if [ -n "$(
        {
          sort -u "${work_dir}/package-infos/${sf}.builds"
          cat "${tmp_dir}/build-list.build-depends"
        } | \
          sort | \
          uniq -d
      )" ]; then
      continue
    fi

    count="/$(
      sort -u "${work_dir}/package-infos/${sf}.builds" | \
        join -1 1 -2 2 -o 2.1 - "${tmp_dir}/dependent-count.build-depends" | \
        sort -u | \
        join -1 1 -2 2 -o 2.1,2.2 - "${tmp_dir}/dependent-count" | \
        tr '/ ' '\n' | \
        grep -vxF '' | \
        sort -u | \
        tr '\n' '/'
    )"
    printf '%s %s\n' \
      "${count}" \
      "${sf}" >> \
      "${tmp_dir}/dependent-count.new"
    find "${tmp_dir}/loops" -type f -maxdepth 1 \
      -exec grep -qxF "${sf}" {} \; \
      -exec rm {} \;
  done < \
    "${tmp_dir}/build-list"

  find "${tmp_dir}/loops" -maxdepth 1 | \
    while read -r loop; do
      if [ ! -f "${loop}" ]; then
        continue
      fi
      if [ -n "$(
          {
            sed '
              s|^|'"${work_dir}"'/package-infos/|
              s|$|.builds|
            ' "${loop}" | \
              xargs -r cat | \
              sort -u
            {
              sed 'p' "${loop}"
              cat "${tmp_dir}/build-list"
            } | \
              sort | \
              uniq -u | \
              sed '
                s|^|'"${work_dir}"'/package-infos/|
                s|$|.build-depends|
              ' | \
              xargs -r grep -hvx 'base\|base-devel' | \
              sort -u
          } | \
            sort | \
            uniq -d
        )" ]; then
        continue
      fi

      count="/$(
        sed '
          s|^|'"${work_dir}"'/package-infos/|
          s|$|.builds|
        ' "${loop}" | \
          xargs -r cat | \
          sort -u | \
        join -1 1 -2 2 -o 2.1 - "${tmp_dir}/dependent-count.build-depends" | \
        sort -u | \
        join -1 1 -2 2 -o 2.1,2.2 - "${tmp_dir}/dependent-count" | \
        tr '/ ' '\n' | \
        grep -vxF '' | \
        sort -u | \
        tr '\n' '/'
      )"
      while read -r sf; do
        printf '%s %s\n' "${count}" "${sf}" >> \
          "${tmp_dir}/dependent-count.new"
        find "${tmp_dir}/loops" -maxdepth 1 -type f -not -name "${loop##*/}" \
          -exec grep -qxF "${sf}" {} \; \
          -exec rm {} \;
      done < \
        "${loop}"

      rm "${loop}"
    done

  cat "${tmp_dir}/dependent-count" "${tmp_dir}/dependent-count.new" | \
    sort -k2,2 | \
    sponge "${tmp_dir}/dependent-count"

done

while read -r count pkg; do
  count=$(
    echo "${count}" | \
      tr '/' '\n' | \
      grep -cvxF ''
  ) || true
  printf '%s %s\n' "${pkg}" "${count}"
done < \
  "${tmp_dir}/dependent-count" | \
  sponge "${work_dir}/dependent-count"