#!/bin/bash

source /etc/de-p1st-repo/arch-repo.cfg || exit



function main(){
  cd "${REMOTE_PKG_DIR}" || return $?
  add_new_to_db          || return $?
  generate_index         || return $?
}


#
# add all packages to database
#
function add_all_to_db(){
  echo "Adding all packages to db ..."
  sort_all_pkgname_pkgver || return $?

  echo "For each package name: Add latest version to database ..."
  for PKGNAME in db/*; do
    PKGNAME=$(basename "${PKGNAME}") || return $? # strip directory and suffix from filename
    add_to_db "${PKGNAME}" || return $?
  done
}
#
# add new packages to database
#
function add_new_to_db(){
  echo "Adding new packages to db ..."
  sort_new_pkgname_pkgver || return $?

  echo "For each new package name: Add latest version to database ..."
  for PKGNAME in "${NEW_PKGNAMES[@]}"; do
    add_to_db "${PKGNAME}" || return $?
  done
}
#
# add package to database
#
function add_to_db(){
  # $1: package name
  local PKGNAME
  PKGNAME="$1"

  #
  # get latest version for $PKGNAME
  #

  # pick one random version as starting point for the latest version
  local LATEST
  for PKGVER in db/"${PKGNAME}"/*; do
    PKGVER=$(basename "${PKGVER}")  # strip directory and suffix from filename
    LATEST="$PKGVER"
    break
  done

  local cmp
  for PKGVER in db/"$PKGNAME"/*; do
    PKGVER=$(basename "${PKGVER}")  # strip directory and suffix from filename

    # compare the currently known latest version
    # with the next version
    cmp=$(vercmp "$LATEST" "$PKGVER") || return $?
    # if the new version is larger, save it as LATEST
    if [ "$cmp" -lt "0" ]; then
      LATEST="$PKGVER"
    fi
  done

  #
  # add latest version of PKGNAME to database
  #

  PKG=$(cat "db/${PKGNAME}/${LATEST}") || return $?
  repo-add --new "${REMOTE_DB_NAME}.db.tar.gz" "${PKG}" || return $?
}


#
# create files "db/$pkgname/$pkgver" with content "$PKG" (path to package file)
#
function sort_all_pkgname_pkgver(){
  echo "Cleanup ..."
  rm -r db || return $?

  echo "Sorting all packages by package name and package version ..."

  for PKG in *.pkg.tar.{xz,zst}; do
    sort_pkgname_pkgver "${PKG}" || return $?
  done
}
#
# create files "db/$pkgname/$pkgver" with content "$PKG" (path to package file)
#
function sort_new_pkgname_pkgver(){
  # return: 0 on success; array $NEW_PKGNAMES

  echo "Sorting new packages by package name and package version ..."

  local NEW_PKGNAMES_TMP=() # list the names from new package-files; may contain duplicates

  mapfile -t PKGS < <(cat new-pkg.txt)
  for PKG in "${PKGS[@]}"; do
    sort_pkgname_pkgver "${PKG}" || return $?
    NEW_PKGNAMES_TMP+=("${PKGNAME}")
  done


  # create array $NEW_PKGNAMES without duplicates
  NEW_PKGNAMES=()
  for NEW_PKGNAME_TMP in "${NEW_PKGNAMES_TMP[@]}"; do
    local contains="0"

    # if NEW_PKGNAMES does already contain NEW_PKGNAME_TMP,
    # then set contains to "1"
    for i in "${NEW_PKGNAMES[@]}"; do
      if [ "${NEW_PKGNAME_TMP}" = "${i}" ]; then
        contains="1";
        break;
      fi
    done

    if [ "${contains}" = "0" ]; then
      NEW_PKGNAMES+=("${NEW_PKGNAME_TMP}")
    fi
  done
}
#
# create files "db/$pkgname/$pkgver" with content "$PKG" (path to package file)
#
function sort_pkgname_pkgver(){
  # $1: PKG (path to package file)
  # return: 0 on success; variables $PKGINFO, $PKGNAME, $PKGVER
  local PKG
  PKG="$1"

  get_pkginfo "$PKG"        || { echo "get_pkginfo failed"; return 1; }
  get_pkgname "$PKGINFO"    || { echo "get_pkgname failed"; echo "Content of PKGINFO: ${PKGINFO}"; return 1; }
  get_pkgver  "$PKGINFO"    || { echo "get_pkgver  failed"; echo "Content of PKGINFO: ${PKGINFO}"; return 1; }

  echo "Creating file ./db/${PKGNAME}/${PKGVER} with content ${PKG} ..."
  mkdir -p "db/${PKGNAME}" || return $?
  echo "${PKG}" > "db/${PKGNAME}/${PKGVER}" || return $?
}


#
# get content of .PKGINFO from package-file
#
function get_pkginfo(){
  # $1: path to package file
  # return: 0 on success; variable $PKGINFO

  if endswith "$1" ".pkg.tar.xz"; then
    PKGINFO=$(tar -xf "$1" -O .PKGINFO --force-local)         || { echo "tar failed"; return 1; }
  elif endswith "$1" ".pkg.tar.zst"; then
    PKGINFO=$(tar -I zstd -xf "$1" -O .PKGINFO --force-local) || { echo "tar failed"; return 1; }
  else
    echo "$1 does not seem to be a package!"
    return 1
  fi
}


#
# get pkgname from $PKGINFO
#
function get_pkgname(){
  # return: 0 on success; variable $PKGNAME

  # remove "pkgname = " as well as tailing whitespace characters
  local tmp
  tmp=$(echo "${PKGINFO}" | grep '^pkgname')                     || { echo "grep failed"; return 1; }
  PKGNAME=$(echo "${tmp}" | sed 's|^pkgname\s*=\s*||; s|\s*$||') || { echo "sed failed"; return 1; }
}
#
# get pkgver from $PKGINFO
#
function get_pkgver(){
  # return: 0 on success; variable $PKGVER

  # remove "pkgver = " as well as tailing whitespace characters
  local tmp
  tmp=$(echo "${PKGINFO}" | grep '^pkgver')                    || { echo "grep failed"; return 1; }
  PKGVER=$(echo "${tmp}" | sed 's|^pkgver\s*=\s*||; s|\s*$||') || { echo "sed failed"; return 1; }
}


# Inspired by: https://stackoverflow.com/questions/2172352/in-bash-how-can-i-check-if-a-string-begins-with-some-value/18558871#18558871
#
# $1 begins with $2
#
beginswith() { case $1 in "$2"*) true;; *) false;; esac; }
#
# $1 ends with $2
#
endswith() { case $1 in *"$2") true;; *) false;; esac; }


#
# generate index.html
#
function generate_index(){
  echo "Generating index.html with links to all packages ..."

  echo "<!DOCTYPE html>
<html>
<head>
<title>${HTML_TITLE}</title>
</head>
<body>
<h1>${HTML_HEADING}</h1>
<p>The sources can be found here: <a href=\"${HTML_LINK_SRC}\">${HTML_LINK_SRC}</a></p>

<ul>
" > index.html

  for PKG in *.pkg.tar.{xz,zst}; do
    echo "<li><a href=\"$PKG\">$PKG</a></li>" >> index.html;
  done

  echo '
</ul>

</body>
</html>' >> index.html
}

main "$@"
