#!/usr/bin/env bash
# Build source packages from nightly builds and upload to PPA

# shellcheck disable=SC2310 # -e will be disabled in if

## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
# shellcheck source=resources/build/builder-full.inc.sh
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE

# shellcheck source=linux/scripts/package-build.inc.sh
. "$(dirname "${THIS_SCRIPT}")/package-build.inc.sh"

builder_describe \
  "Build source packages from nightly builds and upload to PPA" \
  build \
  "--no-download                    Don't download source. Assume keyman-<version> exists as subdirectory of current dir." \
  "--upload                         Upload to launchpad." \
  "--simulate                       Simulate the upload to launchpad." \
  "--no-lintian                     Don't run lintian while creating source package." \
  "--no-sign                        Don't sign the source package." \
  "--dist=DIST                      Only upload this distribution. Default: upload all supported dists." \
  "--packageversion=PACKAGEVERSION  String to append to the package version. Default: '1~sil1'." \
  "--outputdir=OUTPUTDIR            Directory for resulting artifacts. Default: \$KEYMAN_ROOT/linux/launchpad." \
  "--retries=RETRIES                Number of retries on network errors. Default: 5."

builder_parse "$@"

cd "${KEYMAN_ROOT}/linux"

checkPrerequisites

if [[ -z "${OUTPUTDIR:-}" ]]; then
  OUTPUTDIR="${KEYMAN_ROOT}/linux/launchpad"
fi

if builder_has_option --simulate; then
  SIM="-s"
else
  SIM=""
fi

DEBUILD_OPTS=()
if builder_has_option --no-lintian; then
  DEBUILD_OPTS+=("--no-lintian")
fi

if builder_has_option --no-sign; then
  DEBUILD_OPTS+=("--no-sign")
fi

if [[ "${KEYMAN_TIER}" == "stable" ]]; then
  ppa="keyman-ppa:keyman"
elif [[ "${KEYMAN_TIER}" == "beta" ]]; then
  ppa="keyman-ppa:keyman-beta"
else
  ppa="keyman-ppa:keyman-alpha"
fi
echo "ppa: ${ppa}"

function upload_with_retry() {
  local changes_file="$1"
  local retries="$2"
  local sim="$3"
  local ppa="$4"
  local attempt=0
  local max_attempts=$((retries+1))
  local rc=0
  local output

  while (( attempt++ < max_attempts )); do
    builder_echo "Uploading ${changes_file} (attempt ${attempt}/${max_attempts})..."
    set -o pipefail
    # shellcheck disable=SC2312,SC2086  # no quotes for $sim - it might not be set
    output=$(dput ${sim:-} "${ppa}" "${changes_file}" 2>&1 | tee /dev/stderr)
    rc=$?
    set +o pipefail
    if [[ ${rc} == 0 ]]; then
      return 0
    fi
    # Check if error is a network-related error
    if [[ ${rc} == 1 ]] && echo "${output}" | grep -iE 'Connection reset|Connection refused|Network is unreachable|Name or service not known|Connection timed out|Temporary failure|Broken pipe|Connection aborted' > /dev/null 2>&1; then
      if (( attempt < max_attempts )); then
        builder_echo warning "Network error detected, retrying..."
        sleep $((attempt * 5))
      fi
    else
      # Non-network error, fail immediately
      builder_echo error "Upload failed with non-network error (exit code: ${rc})"
      builder_echo error "${output}"
      return "${rc}"
    fi
  done

  builder_echo error "Failed to upload after ${max_attempts} attempts"
  return 1
}

distributions="${DIST:-jammy noble questing resolute}"
packageversion="${PACKAGEVERSION:-1~sil1}"
retries="${RETRIES:-5}"

if ! builder_has_option --no-download; then
  rm -rf launchpad
  mkdir -p launchpad
fi

if ! builder_has_option --no-download; then
  downloadSource launchpad
else
  version=$(cat "${KEYMAN_ROOT}/VERSION.md")
  cd "${OUTPUTDIR}"
fi

cd "keyman-${version:-}"
pwd
cp debian/changelog "../keyman-changelog"
for dist in ${distributions}; do
  cp "../keyman-changelog" debian/changelog
  dch -v "${version}-${packageversion}~${dist}" "source package for PPA"
  dch -D "${dist}" -r ""
  # According to the docs, -S is equivalent to --build=source, but that causes debuild to fail.
  # There is no long option for -sa (passed to dpkg-genchanges)
  debuild "${DEBUILD_OPTS[@]}" --no-check-builddeps --compression=xz -S -sa
done
if builder_has_option --upload || builder_has_option --simulate; then
  cd ..
  for dist in ${distributions}; do
    if ! upload_with_retry "keyman_${version}-${packageversion}~${dist}_source.changes" "${retries}" "${SIM}" "${ppa}"; then
      builder_die "Upload failed for distribution ${dist}"
    fi
  done
fi
