#!/bin/bash

## Copyright (C) 2012 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## Intentional word-splitting of curl command arguments (CURL_RESUME,
## CURL_PROXY, CURL_OPTS, ...); quoting them would break the call.
# shellcheck disable=SC2086

set -x
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
shopt -s inherit_errexit
shopt -s shift_verbose

true "INFO: Currently running script: ${BASH_SOURCE[0]} $*"

MYDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd "$MYDIR"
cd ..
cd help-steps

source pre
source variables

cd "$MYDIR"
cd ..

update_apt_database() {
   $SUDO_TO_ROOT \
      apt-get \
         "${DIST_APTGETOPT[@]}" \
         -o Dir::Etc::sourcelist="$dist_build_sources_list_primary" \
         -o Dir::Etc::sourceparts="-" \
         update
}

local_dependencies() {
   ## developer-meta-files provides dm-reprepro-wrapper

   pushd "$source_code_folder_dist/packages/kicksecure/developer-meta-files/"

   ## Use full path to genmkfile so it does not need to be installed.
   ## This saves a bit build time and allows the bootstrap issue of building genmkfile using genmkfile.
   ## DIST_APTGETOPT gymnastics needed to pass apt sources information to genmkfile without permanently modifying DIST_APTGETOPT.
   local DIST_APTGETOPT_OLD
   DIST_APTGETOPT_OLD=( "${DIST_APTGETOPT[@]}" )
   DIST_APTGETOPT+=(
      -o Dir::Etc::sourcelist="$dist_build_sources_list_primary"
      -o Dir::Etc::sourceparts="-"
   )
   DIST_APTGETOPT_SERIALIZED="$(printf '%s\n' "${DIST_APTGETOPT[@]}")"

   "$source_code_folder_dist/packages/kicksecure/genmkfile/usr/bin/genmkfile" deb-cleanup

   if [ "${make_use_cowbuilder:-}" = "false" ]; then
      "$source_code_folder_dist/packages/kicksecure/genmkfile/usr/bin/genmkfile" deb-build-dep
   fi

   if [ "${make_use_cowbuilder:-}" = "true" ]; then
      ## TODO: not using set_cowbuilder_folders because...
      ##       ${host_architecture} versus ${dist_build_multiarch_package_item}
      cow_folder="$cowbuilder_cache_dir/cow.cow_${host_architecture}"
      base_folder="$cowbuilder_cache_dir/base.cow_${host_architecture}"
      if ! test -d "$cow_folder" ; then
         error "cow_folder does not exist. Did you run 1130_cowbuilder-setup?"
      fi
      if ! test -d "$base_folder" ; then
         error "base_folder does not exist. Did you run 1130_cowbuilder-setup?"
      fi
   fi

   ## Environment variables make_use_lintian, make_use_cowbuilder, dist_build_apt_codename if set are expected to be passed.
   "$source_code_folder_dist/packages/kicksecure/genmkfile/usr/bin/genmkfile" deb-pkg

   "$source_code_folder_dist/packages/kicksecure/genmkfile/usr/bin/genmkfile" deb-install

   DIST_APTGETOPT=( "${DIST_APTGETOPT_OLD[@]}" )
   DIST_APTGETOPT_SERIALIZED="$(printf '%s\n' "${DIST_APTGETOPT[@]}")"

   popd
}

live-build_installation() {
   if [ ! "${dist_build_iso:-}" = "true" ]; then
      true "INFO: Not installing live-build, because not building an ISO."
      return 0
   fi

   local restore_uncommitted_state
   restore_uncommitted_state='y'

   ## live-build's manpages must be built first, or it will fail to
   ## install. However, building the manpages modifies the source tree,
   ## and we don't want to overwrite any uncommitted changes the user may
   ## have. We therefore make a "checkpoint" commit that we almost
   ## immediately undo, preserving any uncommitted changes. This does
   ## result in all modified files becoming unstaged, which isn't perfect
   ## but isn't horrible either. Preserving which files are staged and
   ## which ones are not is probably difficult.

   pushd "$source_code_folder_dist/live-build"

   ## Do not proceed if the working tree is unclean.
   ## provided by: help-steps/pre
   ## Actually not needed, ./build-steps.d/1100_sanity-tests should cover this already.
   #nothing_to_commit_test

   ## Preserve uncommitted changes
   #git add -A
   #git commit -m 'checkpoint' || {
      #restore_uncommitted_state='n'
      #true
   #}

   ## Build live-build man pages.
   ## This makes the ./manpages/ folder dirty.#
   ## Only required when using "make install".
   ## No longer required since building and installing a deb package.
   #make -C manpages update
   #make -C manpages build

   ## If live-build is installed, "$SUDO_TO_ROOT make install" would fail.
   #if [ "$(dpkg-query --show --showformat='${Status}\n' live-build)" = 'install ok installed' ]; then
      #error "Package live-build must not be installed."
   #fi

   ## Install live-build.
   ## Fast. Simple. But can lead to broken permissions because live-build uses 'cp -a'.
   #$SUDO_TO_ROOT make install
   ## Therefore building with genmkfile, cowbuilder.
   ## Setting 'make_use_lintian=false' because live-build upstream is not lintian warning free.
   ## DIST_APTGETOPT gymnastics needed to pass apt sources information to genmkfile without permanently modifying DIST_APTGETOPT.
   local DIST_APTGETOPT_OLD
   DIST_APTGETOPT_OLD=( "${DIST_APTGETOPT[@]}" )
   DIST_APTGETOPT+=(
      -o Dir::Etc::sourcelist="$dist_build_sources_list_primary"
      -o Dir::Etc::sourceparts="-"
   )
   DIST_APTGETOPT_SERIALIZED="$(printf '%s\n' "${DIST_APTGETOPT[@]}")"
   make_use_lintian=false "$source_code_folder_dist/packages/kicksecure/genmkfile/usr/bin/genmkfile" deb-icup
   DIST_APTGETOPT=( "${DIST_APTGETOPT_OLD[@]}" )
   DIST_APTGETOPT_SERIALIZED="$(printf '%s\n' "${DIST_APTGETOPT[@]}")"

   ## Revert back to the checkpoint
   #git add -A

   ## git status
   ## > modified:   manpages/
   ## Back to pristine source code.
   ## Delete auto generated manpages.
   ## Doing it for all of the live-build source code might make things more cumbersome for developers.
   #git reset --hard HEAD
   ## Only required when using "make install".
   ## No longer required since building and installing a deb package.
   #git checkout HEAD -- ./manpages/

   ## Restore uncommitted source tree state
   #if [ "${restore_uncommitted_state:-}" = 'y' ]; then
      #git reset HEAD^
   #fi

   ## Sanity test.
   #nothing_to_commit_test

   popd

   true
}

virtualbox_windows_installer_download() {
   if [ ! "${dist_build_windows_installer:-}" = "true" ]; then
      true "$0: INFO: Skip ${FUNCNAME[0]}, because dist_build_windows_installer is not set to true."
      return 0
   fi

   ## Kept in derivative-maker source code folder:
   ## - SHA256SUMS
   ## - download.txt
   ## reason: security
   ##
   ## Downloaded from virtualbox.org during build script:
   ## - VirtualBox installer (example file name: VirtualBox-7.0.18-162988-Win.exe)
   ## reason: Larger than 100 MB and can therefore not be added to git.

   mkdir --parents "$binary_build_folder_dist/virtualbox-windows-installer-binary"
   ## dm-virtualbox-installer-exe-verify-windows requires being in the folder.
   pushd "$binary_build_folder_dist/virtualbox-windows-installer-binary" >/dev/null

   cp --verbose "$source_code_folder_dist/windows/virtualbox/download.txt" "$binary_build_folder_dist/virtualbox-windows-installer-binary/"
   cp --verbose "$source_code_folder_dist/windows/virtualbox/SHA256SUMS" "$binary_build_folder_dist/virtualbox-windows-installer-binary/"

   curl_download_target_url=$(cat -- "$source_code_folder_dist/windows/virtualbox/download.txt")
   ## Exact filename is required for SHA256SUMS verification.
   versioned_virtualbox_file_name=$(basename "$curl_download_target_url")

   ## XXX: Not easy due to dependencies.
   #CURL_PRGRS="$source_code_folder_dist/packages/kicksecure/helper-scripts/usr/libexec/helper-scripts/curl-prgrs"
   CURL_PRGRS="curl"

   ## Resume must stay OFF for the two downloads below (VirtualBox Windows
   ## installer and vc_redist). With resume enabled they fail:
   ## > curl: (22) The requested URL returned error: 416
   ## 'help-steps/variables' now exports CURL_RESUME="--continue-at -" by
   ## default (to match tb-updater), so explicitly clear it here. Previously
   ## this was a commented-out assignment, which sufficed only while the
   ## global default was empty.
   CURL_RESUME=""

   ## TODO
   #CURL_PROXY=
   CURL_FORCE_SSL="--tlsv1.3 --proto =https"
   #CURL_OPTS="--verbose"
   curl_download_max_time="3600"

   CURL_OUT_FILE="$binary_build_folder_dist/virtualbox-windows-installer-binary/$versioned_virtualbox_file_name"

   $CURL_PRGRS \
      ${CURL_RESUME:-} \
      --fail \
      ${CURL_PROXY:-} \
      $CURL_FORCE_SSL \
      --retry-connrefused \
      --retry 10 \
      --retry-delay 60 \
      --max-time "$curl_download_max_time" \
      --location \
      ${CURL_OPTS:-} \
      --output "$CURL_OUT_FILE" \
      "$curl_download_target_url"

   ## provided by package: developer-meta-files
   ## Would also notice if multiple VirtualBox-*-Win.exe files are inside the virtualbox-windows-installer-binary folder.
   dm-virtualbox-installer-exe-verify-windows

   CURL_OUT_FILE="$binary_build_folder_dist/virtualbox-windows-installer-binary/vc_redist.x64.exe"

   ## Unstable link.
   #vc_redist_target_url="https://aka.ms/vs/17/release/vc_redist.x64.exe"
   ##
   ## curl --silent --head https://aka.ms/vs/17/release/vc_redist.x64.exe | grep Location
   ## Location: https://download.visualstudio.microsoft.com/download/pr/c7dac50a-e3e8-40f6-bbb2-9cc4e3dfcabe/1821577409C35B2B9505AC833E246376CC68A8262972100444010B57226F0940/VC_redist.x64.exe
   ##
   ## https://www.virustotal.com/gui/url/2d88412837fb27ada5ee7499cb64c458b8e6c1c4f741a1479bc427f487f126ec
   ##
   ## https://web.archive.org/web/20241113122717/https://download.visualstudio.microsoft.com/download/pr/c7dac50a-e3e8-40f6-bbb2-9cc4e3dfcabe/1821577409C35B2B9505AC833E246376CC68A8262972100444010B57226F0940/VC_redist.x64.exe
   vc_redist_target_url="https://download.visualstudio.microsoft.com/download/pr/c7dac50a-e3e8-40f6-bbb2-9cc4e3dfcabe/1821577409C35B2B9505AC833E246376CC68A8262972100444010B57226F0940/VC_redist.x64.exe"

   curl_download_target_url="$vc_redist_target_url"

   ## Microsoft only supports tlsv1.2 at time of writing.
   CURL_FORCE_SSL="--tlsv1.2 --proto =https"

   $CURL_PRGRS \
      ${CURL_RESUME:-} \
      --fail \
      ${CURL_PROXY:-} \
      $CURL_FORCE_SSL \
      --retry-connrefused \
      --retry 10 \
      --retry-delay 60 \
      --max-time "$curl_download_max_time" \
      --location \
      ${CURL_OPTS:-} \
      --output "$CURL_OUT_FILE" \
      "$curl_download_target_url"

   dm-virtualbox-installer-vc_redist-verify-windows

   popd >/dev/null

   true
}

main() {
   update_apt_database "$@"
   local_dependencies "$@"
   live-build_installation "$@"
   virtualbox_windows_installer_download "$@"
}

main "$@"
