#!/bin/bash

## Copyright (C) 2023 - 2024 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -x
set -e
true "$0: START"

run_cmd() {
  [ -n "$TESTING_MODE" ] || TESTING_MODE=0
  if [ "$TESTING_MODE" -eq 1 ]; then
    set +x
    echo "$@"
  else
    "$@"
  fi
}

## This path to this script in the derivative-maker source code folder is help-steps/dm-build-official.
## Go to root of the source code folder.
## Only needed if one would 'cd ./help-steps' beforehand.
#run_cmd cd ..

true "INFO: 0: $0"

if [ "$CI" = "true" ]; then
  true "INFO: Skipping test if folder ~/.ssh exists on CI."
else
  run_cmd test -d ~/.ssh
fi

## Ordered as follows for the following reasons:
## - 1) Build '--flavor kicksecure-xfce' because building ISO, which is newer,
##      therefore more prone to build issues. Error out quicker is better.
## - 2) Build '--flavor whonix-gateway-xfce' because it is required to be able to
##      run dm-prepare-release due to unified ova files.
## - 3) Build '--flavor whonix-workstation-xfce' because it is the most
##   complex, because of downloading Tor Browser as well as when used with
##   '--target windows', because:
##     - *_prepare-build-machine downloads VirtualBox-*-Win.exe
##     - dm-prepare-release builds Whonix Windows Installer
## - 4) Build CLI flavors because the least likely to have build issues.
# if [ "$CI" = "true" ]; then
#   ## Build fewer flavors on CI to save build time.
#   ## It is unlikely that building an Xfce flavor would succeed while the CLI flavor would fail.
#   [ -n "$flavors_list" ] || flavors_list=(
#     kicksecure-xfce
#     whonix-gateway-xfce
#     whonix-workstation-xfce
#   )
# else
  [ -n "$flavors_list" ] || flavors_list=(
    kicksecure-xfce
    kicksecure-cli
    whonix-gateway-xfce
    whonix-workstation-xfce
    whonix-gateway-cli
    whonix-workstation-cli
  )
# fi

build_upload_noninteractive=true
export build_upload_noninteractive

dist_build_redistributable=true
export dist_build_redistributable

if [ "$dist_build_redistributable" = "true" ]; then
  build_args+=(--repo true)
  build_args+=(--tb closed)
fi

if echo "$@" | grep --quiet "remote-derivative-packages true" ; then
  ## Skip upload of debug images.
  rsync_cmd="true simulate-only"
  export rsync_cmd
fi

[ -n "$architecture" ] || architecture=$(dpkg --print-architecture)
build_args+=(--arch $architecture)

multi_target_args=()

case $architecture in
  amd64)
    ## '--target virtualbox'
    ## Build VirtualBox ova. (amd64 for Windows, Linux, Mac)
    multi_target_args+=("--target" "virtualbox")
    multi_target_args+=("--target" "qcow2")
  ;;
  arm64)
    ## Build VirtualBox ova. (arm64 for Mac M1, M2 and maybe Linux.)
    multi_target_args+=("--target" "virtualbox")
    #multi_target_args+=("--target" "qcow2")
    ## Only on arm64 for Mac M1, M2.
    #multi_target_args+=("--target" "utm")
  ;;
  *)
    ## '--target qcow2' might be the most universal.
    multi_target_args+=("--target" "qcow2")
  ;;
esac

## multi_target_args comment:
## Cannot mix,
## * 1) '--target iso', and,
## * 2) "${multi_target_args[@]}"
## because no ISO should be build for Whonix-Gateway, Whonix-Workstation.
## (Maybe in the future for Whonix-Host.)
## The ISO should only be built for Kicksecure-Xfce for now.

for flavor_item in "${flavors_list[@]}"; do
  ## Not yet using multi_target_args as the sanity test for Whonix-Gateway ISO would complain that the VMs
  ## have not been built yet.
  run_cmd ./build-steps.d/*_sanity-tests "${build_args[@]}" --target windows "${multi_target_args[@]}" --flavor "$flavor_item" "$@"
done

## Use both,
## * 1) '--target iso', and,
## * 2) "${multi_target_args[@]}"
## for prepare-build-machine, because additional dependencies are required for building the ISO.
run_cmd ./build-steps.d/*_prepare-build-machine "${build_args[@]}" --target iso --target windows "${multi_target_args[@]}" --flavor internal "$@"

run_cmd ./build-steps.d/*_cowbuilder-setup "${build_args[@]}" --target iso --target windows "${multi_target_args[@]}" --flavor internal "$@"
run_cmd ./build-steps.d/*_local-dependencies "${build_args[@]}" --target iso --target windows "${multi_target_args[@]}" --flavor internal "$@"

export dist_build_raw_base_image_create=true
## '--flavor internal' would lead to variable dist_build_hostname being unset.
## Therefore using '--flavor kicksecure-cli' to create a raw base image.
## '--target iso' must not be used because ISO is nowadays created using live-build, not create-raw-image.
## create-raw-image would do nothing if using '--target iso'.
run_cmd ./build-steps.d/*_create-raw-image "${build_args[@]}" "${multi_target_args[@]}" --flavor kicksecure-cli "$@"
unset dist_build_raw_base_image_create

## '--target iso' is required to download calamares from backports.
run_cmd ./build-steps.d/*_create-debian-packages "${build_args[@]}" --target iso "${multi_target_args[@]}" --flavor internal "$@"

SKIP_SCRIPTS+=" sanity-tests "
SKIP_SCRIPTS+=" prepare-build-machine "
SKIP_SCRIPTS+=" cowbuilder-setup "
## Using cached_binary_image_raw_file instead because we will set dist_build_use_cached_raw_base_image=true.
## Variable cached_binary_image_raw_file will result in create-raw-image simply making a copy of the exiting raw image.
#SKIP_SCRIPTS+=" create-raw-image "
SKIP_SCRIPTS+=" local-dependencies "
SKIP_SCRIPTS+=" create-debian-packages "
export SKIP_SCRIPTS

dist_build_use_cached_raw_base_image=true
export dist_build_use_cached_raw_base_image

## Build and dm-prepare-release.
for flavor_item in "${flavors_list[@]}"; do
  case $flavor_item in
    kicksecure-xfce)
      ## For now, create an ISO only for Kicksecure Xfce.
      ## Not for Kicksecure CLI.
      ## Not yet for Whonix.
      true "INFO: ISO build flavor."
      run_cmd ./derivative-maker "${build_args[@]}" --target iso --flavor "$flavor_item" "$@"
      ;;
    *)
      true "INFO: Non-ISO build flavor."
      ;;
  esac

  run_cmd ./derivative-maker "${build_args[@]}" "${multi_target_args[@]}" --flavor "$flavor_item" "$@"
done

## Same source code for all of the following: Xfce vs CLI and Kicksecure vs Whonix.
run_cmd dm-prepare-release --target source --flavor "kicksecure-xfce" "$@"
run_cmd dm-upload-images --target source --flavor "kicksecure-xfce" "$@"
run_cmd dm-upload-images --target source --flavor "whonix-workstation-xfce" "$@"

if [ "$architecture" = "amd64" ]; then
  ## Also build the Whonix-Windows-Installer.
  run_cmd dm-prepare-release --target windows --flavor whonix-workstation-xfce
  run_cmd dm-upload-images --target windows --flavor whonix-workstation-xfce
fi

## Uploading.
for flavor_item in "${flavors_list[@]}"; do
  if echo "$flavor_item" | grep --quiet "gateway" ; then
    ## Not needed for gateway due to unified images.
    continue
  fi

  case $flavor_item in
    kicksecure-xfce)
      true "INFO: ISO build flavor."
      run_cmd dm-upload-images "${build_args[@]}" --target iso --flavor "$flavor_item" "$@"
      ;;
    *)
      true "INFO: Non-ISO build flavor."
      ;;
  esac

  ## Cannot use "${multi_target_args[@]}" here, because
  ## help-steps/variables variable dist_server_with_upload_location_list is does not support multiple "--target"'s.
  for ((i=0; i<${#multi_target_args[@]}; i+=2)); do
    target_arg="${multi_target_args[i]}"
    target_value="${multi_target_args[i+1]}"
    run_cmd dm-upload-images "${build_args[@]}" $target_arg $target_value --flavor "$flavor_item" "$@"
  done
done

true "$0: END"
