#!/usr/bin/env bash
set -euo pipefail
unset TMPDIR_WRK

# ------------------------------------------------------------------------------
# METADATA
# ------------------------------------------------------------------------------

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Script location, independant of calling location
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")" # Script name

# Guard from being sourced instead of executed
(return 0 2>/dev/null) && { echo "Do not source this script." >&2; return 1; }

# ------------------------------------------------------------------------------
# DEFAULT VALUES
# ------------------------------------------------------------------------------

VERBOSE=false
POSITIONAL_ARGS=()

# ------------------------------------------------------------------------------
# LOGGING
# ------------------------------------------------------------------------------

log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2; }
info() { [[ "$VERBOSE" == true ]] && log "[DBG] $*" || true; }
warn() { log "[WRN] $*"; }
error() { log "[ERR] $*"; }
die() { error "$*"; exit 1; }

# ------------------------------------------------------------------------------
# TEMPORARY DIRECTORY MANAGEMENT
# ------------------------------------------------------------------------------
# On exit cleanup the optional temp directory used.
# Refuses to delete anything other that /tmp/*

TMPDIR_WRK=""

cleanup() {
	if [[ -n "$TMPDIR_WRK" && -d "$TMPDIR_WRK" ]]; then
		case "$TMPDIR_WRK" in
			/tmp/*) rm -rf "$TMPDIR_WRK" ;;
			*) warn "Refusing to delete suspicious path: $TMPDIR_WRK" ;;
		esac
	fi
}
trap cleanup EXIT

# ------------------------------------------------------------------------------
# USAGE
# ------------------------------------------------------------------------------
# Explain the purpose of the script and how to use it

usage() {
	cat << USAGE
Usage: $SCRIPT_NAME [OPTIONS] git_repository

Build packages from a git repository in a container.

Options:
  -b, --branch       Specify git repository branch to checkout before build
  -v, --verbose      Enable verbose output
  -h, --help         Show this help message and exit
USAGE
}

# ------------------------------------------------------------------------------
# CONFIG FILE
# ------------------------------------------------------------------------------

config_file() {
	if [[ -n "${BUILD_PACK_CONF:-}" ]]; then
		info "Using custom config file $BUILD_PACK_CONF"
		source "$BUILD_PACK_CONF"
	else
		case "$PACKAGE_TYPE" in
			deb) source /etc/setup/packaging/build_deb.conf ;;
			rpm) source /etc/setup/packaging/build_rpm.conf ;;
			*) die "Unknown package type: $1. Use --help for usage." ;;
		esac
	fi
}

# ------------------------------------------------------------------------------
# PARSING ARGUMENTS
# ------------------------------------------------------------------------------
# Add arguments there and their logic
# Positional arguments without flag are treated in validate

parse_args() {
	while [[ "$#" -gt 0 ]]; do
		case "$1" in
			-v|--verbose) VERBOSE=true ;;
			-h|--help) usage; exit 0 ;;
			-b|--branch) shift; GIT_BRANCH=$1 ;;
			-*) die "Unknown option: $1. Use --help for usage." ;;
			*) POSITIONAL_ARGS+=("$1") ;;
		esac
		shift
	done
}

parse_positional_args() {
	PACKAGE_TYPE="$1"
	GIT_REPO="$2"
}

# ------------------------------------------------------------------------------
# VALIDATE USER INPUTS
# ------------------------------------------------------------------------------
# Verify user inputs there
# Necessary flag, positional arguments values, numbers, ...

# Number of arguments that this script needs at minimum
ARG_COUNT=1

validate() {
	if [[ "${#POSITIONAL_ARGS[@]}" -lt "$ARG_COUNT" ]]; then
		die "Expected $ARG_COUNT arguments, got ${#POSITIONAL_ARGS[@]}"
	fi
	PACKAGE_TYPE="${POSITIONAL_ARGS[0]}"
	case "$PACKAGE_TYPE" in
		deb|rpm) ;;
		*) die "Invalid package type $PACKAGE_TYPE. Valid ones are deb, rpm" ;;
	esac
	GIT_REPO="${POSITIONAL_ARGS[1]}"
	if [[ -z "$GIT_REPO" ]]; then die "GIT_REPO - git repository name is required"; fi
	if [[ -z "$EXCHANGE_DIR" ]]; then die "EXCHANGE_DIR - exchange directory is required"; fi
	if [[ -z "$PODMAN_IMAGE" ]]; then die "PODMAN_IMAGE - podman image is required"; fi
	if [[ -z "$BUILD_DIR" ]]; then die "BUILD_DIR - build directory is required"; fi
	if [[ -z "$GIT_URL" ]]; then die "GIT_URL - git repository URL is required"; fi
}

# ------------------------------------------------------------------------------
# MAIN
# ------------------------------------------------------------------------------

build_in_container() {
	podman run --rm -v "$EXCHANGE_DIR":/package "$PODMAN_IMAGE" \
		bash -c "$PREBUILD_DEPENDANCIES &&
			mkdir $BUILD_DIR &&
			cd $BUILD_DIR &&
			git clone --recurse-submodules${GIT_BRANCH:+ -b $GIT_BRANCH} $GIT_URL/$GIT_REPO.git &&
			cd $GIT_REPO &&
			$BUILD_DEPENDANCIES &&
			$BUILD_COMMAND &&
			cp $OUT_PACKAGES /package
		"
}


main() {
	parse_args "$@"
	parse_positional_args "${POSITIONAL_ARGS[@]}"
	config_file
	validate

	info "Starting $SCRIPT_NAME"

	# Create a temp directory that will be cleaned up, uncomment if needed
	#TMPDIR_WRK="$(mktemp -d)"

	build_in_container

	local packages=( "$EXCHANGE_DIR"/* )
	info "Done building ${#packages[@]} packages in $EXCHANGE_DIR"
}

main "$@"
