#!/bin/bash

translation="\
-e 's/\b''pacman''\b/''apt''/' \
-e 's/\b''dtc''\b/''device-tree-compiler''/' \
-e 's/\b''openssh''\b/''openssh-server''/' \
-e 's/\b''mmc-utils-git''\b/''mmc-utils''/' \
-e 's/\b''inetutils''\b/''hostname''/' \
-e 's/\b''uboot-tools''\b/''u-boot-tools''/' \
-e 's/\b''iptables-nft''\b/''iptables''/' \
-e 's/\b''run-parts''\b/''debianutils''/' \
-e 's/\b''dbus-broker-units''\b//' \
-e 's/\b''base''\b/''libpam-systemd systemd-timesyncd systemd-resolved kmod zstd iputils-ping iw file''/' \
-e 's/\b''armv7h''\b/''armhf''/' \
-e 's/\b''x86_64''\b/''amd64''/' \
-e 's/\b''aarch64''\b/''arm64''/' \
-e 's/\b''any''\b/''all''/' \
"

pool="main"
dist="stable"
exclude="usr/share/libalpm"
repoarches="arm64"

while [ "${1:-}" != '' ]; do
  case "$1" in
  '-r' | '--repo-add') shift; repopath="${1}" ;;
  *) cat <<-EOF
	Usage: $(basename "$0") [OPTION]...
	  -r --repo-add            Path to apt-repo to create/update
	EOF
    exit 1
    ;;
  esac
  shift
done

function control {
  ( cat <<-EOF #| tee $rootfsdir/etc/pacman.conf
	Package: $package
	Version: $pkgver
	Vendor: none
	Architecture: $arch
	Section: default
	Priority: optional
	EOF
  putinfo      Description    pkgdesc
  putinfo      Homepage       url
  putinfo      Installed-Size size
  putinfocomma Depends        depend
  putinfocomma Conflicts      conflict
  putinfocomma Provides       provides
  putinfocomma Replaces       replaces
  putinfo      License        license
  putinfo      Maintainer     packager
  [[ "$arch" == "all" ]] && echo "Multi-Arch: foreign"
  ) >deb/$package/control/control
}

function prerm {
  declare -F pre_remove >/dev/null || return
  ( 
    echo -e "#!/bin/bash\n# Source from archlinux package .INSTALL"
    cat "pkg/$package/.INSTALL"
    cat <<-'EOF'
	dummy() {
	    :
	}
	export DEB_MAINT_PARAMS="$*"
	if [ "${1}" = "remove" -a -z "${2}" ]; then
	    declare -F pre_remove >/dev/null && pre_remove || exit 0
	elif [ "${1}" = "upgrade" ]; then
	    declare -F dummy >/dev/null && dummy || exit 0
	elif echo "${1}" | grep -E -q "(fail|abort)"; then
	    echo "Failed to install before the pre-removal script was run." >&2
	    exit 1
	fi
	EOF
  ) >deb/$package/control/prerm
}

function postrm {
  declare -F post_remove >/dev/null || return
  (
    echo -e "#!/bin/bash\n# Source from archlinux package .INSTALL"
    cat "pkg/$package/.INSTALL"
    cat <<-'EOF'
	dummy() {
	    :
	}
	export DEB_MAINT_PARAMS="$*"
	if [ "${1}" = "remove" -o "${1}" = "abort-install" ]; then
	    declare -F post_remove >/dev/null && post_remove || exit 0
	elif [ "${1}" = "purge" -a -z "${2}" ]; then
	    declare -F post_remove >/dev/null && post_remove || exit 0
	elif [ "${1}" = "upgrade" ]; then
	    declare -F dummy >/dev/null && dummy || exit 0
	elif echo "${1}" | grep -E -q '(fail|abort)'; then
	    echo "Failed to install before the post-removal script was run." >&2
	    exit 1
	fi
	EOF
  ) >deb/$package/control/postrm
}

function preinst {
  declare -F pre_upgrade >/dev/null || declare -F pre_install >/dev/null || return
  (
    echo -e "#!/bin/bash\n# Source from archlinux package .INSTALL"
    cat "pkg/$package/.INSTALL"
    cat <<-'EOF'
	export DEB_MAINT_PARAMS="$*"
	if [ "${1}" = "install" -a -z "${2}" ]; then
	    declare -F pre_install >/dev/null && pre_install || exit 0
	elif [ "${1}" = "upgrade" -a -n "${2}" ]; then
	    declare -F pre_upgrade >/dev/null && pre_upgrade "${2}" || exit 0
	elif [ "${1}" = "install" -a -n "${2}" ]; then
	    declare -F pre_upgrade >/dev/null && pre_upgrade "${2}" || exit 0
	elif echo "${1}" | grep -E -q '(fail|abort)'; then
	    echo "Failed to install before the pre-installation script was run." >&2
	    exit 1
	fi
	EOF
  ) >deb/$package/control/preinst
}

function postinst {
  declare -F post_upgrade >/dev/null || declare -F post_install >/dev/null || return
  (
    echo -e "#!/bin/bash\n# Source from archlinux package .INSTALL"
    cat "pkg/$package/.INSTALL"
    cat <<-'EOF'
	export DEB_MAINT_PARAMS="$*"
	if [ "${1}" = "configure" -a -z "${2}" ] || [ "${1}" = "abort-remove" ]; then
	    declare -F post_install >/dev/null && post_install || exit 0
	elif [ "${1}" = "configure" -a -n "${2}" ]; then
	    declare -F post_upgrade >/dev/null && post_upgrade "${2}" || exit 0
	elif echo "${1}" | grep -E -q "(abort|fail)"; then
	    echo "Failed to install before the post-installation script was run." >&2
	    exit 1
	fi
	EOF
  ) >deb/$package/control/postinst
}

do_hash() {
  echo "${1}:"
  for f in $(find main -type f); do
    [[ "$f" == "Release" ]] && continue
    [[ "$f" == "Release.gpg" ]] && continue
    [[ "$f" == "InRelease" ]] && continue
    echo " $(${2} ${f}  | cut -d" " -f1) $(wc -c $f)"
  done
}

release() {(
  cat <<-EOF
	Origin: EricWoud Repository
	Label: EricWoud
	Suite: ${dist}
	Codename: ${dist}
	Version: 1.0
	Architectures: ${repoarches}
	Components: ${pool}
	Description: My repository for BPI Router boards
	Date: $(date -Ru)
	EOF
  cd "dists/${dist}"
  do_hash "MD5Sum" "md5sum"
  do_hash "SHA1"   "sha1sum"
  do_hash "SHA256" "sha256sum"
)}

function repo_rem_old_deb {
    [ -z "${repopath}" ] && return
    (cd "${repopath}"
    pkgline=$(grep "Package:" "pool/${pool}/${debfile}.txt")
    for samepkg in $(grep -lrnw pool/${pool}/*.txt -e "^${pkgline}$" | cut -d':' -f1); do
      [[ "pool/${pool}/${debfile}" == "${samepkg%.txt}" ]] && continue
      rm -vf "${samepkg%.txt}."*
    done)
}

function repo_update {
    [ -z "${repopath}" ] && return
    (
      cd "${repopath}"
      for ra in $repoarches; do
        mkdir -p dists/${dist}/${pool}/binary-${ra}
        cat pool/${pool}/*_${ra}.txt pool/${pool}/*_all.txt >dists/${dist}/${pool}/binary-${ra}/Packages
        cat dists/${dist}/${pool}/binary-${ra}/Packages | gzip -9 \
           >dists/${dist}/${pool}/binary-${ra}/Packages.gz
      done
      release >dists/${dist}/Release
      cat dists/${dist}/Release | gpg -abs > dists/${dist}/Release.gpg
      gpg --batch --yes --clear-sign --output dists/${dist}/InRelease dists/${dist}/Release
    )
}

function getinfo {
  local p q
  for p in $(grep -e "^${1}" pkg/$package/.PKGINFO | cut -d= -f2); do
    p=$(echo $p | cut -d'<' -f1 | cut -d'>' -f1 | cut -d'=' -f1 | \
        xargs -a <(echo -n "${translation}") sed)
    q+=($p)
  done
  echo ${q[*]}
}

function putinfo {
  local s=$(getinfo "${2}")
  [ -z "${s}" ] && return
  echo "${1}: ${s}" | xargs
}

function putinfocomma {
  local s=$(getinfo "${2}" | sed -e 's/ /, /g')
  [ -z "${s}" ] && return
  echo "${1}: ${s}" | xargs
}

[ ! -f "PKGBUILD" ] && exit 1
deb=$(realpath deb)

rm -rf "deb/"*

if [ -n "${repopath}" ]; then
  mkdir -p "${repopath}/pool/${pool}" "${repopath}/dists/${dist}"
fi

for ex in ${exclude}; do
  exdata+=("--exclude=./${ex}")
  exfind+=("-not ( -path "${ex}" -prune )")
done

for package in $(cd pkg; ls); do
  mkdir -p "deb/$package/control"

  unset pre_remove
  unset pre_upgrade
  unset pre_install
  unset post_remove
  unset post_upgrade
  unset post_install

  pkgver=$(getinfo pkgver | tr ':' '.')
  arch=$(getinfo arch)
  debfile="${package}_${pkgver}_${arch}"

  [ -f "pkg/$package/.INSTALL" ] && source "pkg/$package/.INSTALL"

  conffiles="$(cd pkg/$package; find etc/* etc/.* -type f 2>/dev/null | sed  's/^/\//')"
  md5sums="$(  cd pkg/$package; find * ${exfind[*]} -type f -exec md5sum '{}' \; 2>/dev/null)"

  control          
  preinst          
  postinst
  prerm
  postrm
  echo "2.0"                                   >deb/$package/debian-binary
  [ -n "${conffiles}" ] && echo "${conffiles}" >deb/$package/control/conffiles
  [ -n "${md5sums}" ]   && echo "${md5sums}"   >deb/$package/control/md5sums
  chmod 755 deb/$package/control/*

  (cd pkg/$package; files=$(shopt -s nullglob; echo ./*); [ -z "$files" ] && files="--files-from /dev/null"
                            fakeroot tar -cz "${exdata[*]}" -f "$deb/$package/data.tar.gz" $files)
  (cd deb/$package/control; fakeroot tar -cz                -f "$deb/$package/control.tar.gz" ./*)
  (cd deb/$package        ; fakeroot  ar -cr                   "$deb/${debfile}.deb" \
                                        "debian-binary" "control.tar.gz" "data.tar.gz")
# tar -t -f "$deb/$package/data.tar.gz"

  if [ -z "${repopath}" ]; then
    echo "Created: deb/${debfile}.deb"
    continue
  fi

  mv -f "$deb/${debfile}.deb" "${repopath}/pool/${pool}/${debfile}.deb"
  ( cat <<-EOF
	Filename: pool/${pool}/${debfile}.deb
	Size: $(stat -c %s  "${repopath}/pool/${pool}/${debfile}.deb")
	MD5Sum: $(md5sum    "${repopath}/pool/${pool}/${debfile}.deb" | cut -d' ' -f1 | xargs)
	SHA1: $(  sha1sum   "${repopath}/pool/${pool}/${debfile}.deb" | cut -d' ' -f1 | xargs)
	SHA256: $(sha256sum "${repopath}/pool/${pool}/${debfile}.deb" | cut -d' ' -f1 | xargs)
	EOF
    cat deb/$package/control/control
    echo
  ) > "${repopath}/pool/${pool}/${debfile}.txt"
    
  repo_rem_old_deb

  echo "Added to repo: pool/${pool}/${debfile}.deb"

done

repo_update

exit 0

