#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2026 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
# Update the version and recompute the SHA256 checksum in the cmake module for libs, drivers, container plugin and
# rules.
#
# Usage:
#   ./update-deps-version libs      <version>
#   ./update-deps-version drivers   <version>
#   ./update-deps-version container <version>
#   ./update-deps-version rules     <version>
#
# <version> can be a commit hash, tag, or branch name for libs/drivers, a release tag (e.g. "0.7.0") for container
# plugin and rules.

set -euo pipefail

REPO_ROOT="$(git rev-parse --show-toplevel)"

usage() {
	echo "Usage: $(basename "$0") {libs|drivers|container|rules} <version>" >&2
	exit 1
}

# Stream a URL directly into sha256sum and print the hash.
sha256_of_url() {
	local url="$1"
	echo "Computing SHA256 for ${url} ..." >&2
	if command -v curl &>/dev/null; then
		curl -fsSL --retry 3 "${url}" | sha256sum | awk '{print $1}'
	elif command -v wget &>/dev/null; then
		wget -q --tries=3 -O - "${url}" | sha256sum | awk '{print $1}'
	else
		echo "Error: neither curl nor wget found" >&2
		exit 1
	fi
}

# Update the version and SHA256 checksum for libs or drivers. The repo name (<org>/<name>) is read from <cmake_file> by
# matching `set(<repo_var> "...")` and used to compose the download URL.
#
# Usage: update_libs_or_drivers_dep <cmake_file> <version> <repo_var> <version_var> <checksum_var>
update_libs_or_drivers_dep() {
	local CMAKE_FILE="$1"
	local VERSION="$2"
	local REPO_VAR="$3"
	local VERSION_VAR="$4"
	local CHECKSUM_VAR="$5"

	local REPO
	REPO="$(grep -oP "set\(${REPO_VAR}\s+\"\K[^\"]+" "${CMAKE_FILE}")"
	echo "Repo: ${REPO}, Version: ${VERSION}"

	local SHA256
	SHA256="$(sha256_of_url "https://github.com/${REPO}/archive/${VERSION}.tar.gz")"
	echo "  SHA256: ${SHA256}"

	# note: in the following `sed` expressions, `-z` is required in order for `[[:space:]]+` to span across newlines.

	# Update the version string in the cmake file, skipping the "0.0.0-local" one by temporarily swapping it with a
	# placeholder and restoring it at the end (note: this is required because `sed` has no negative lookahead`).
	sed -z -i -E \
		-e 's/"0\.0\.0-local"/PLACEHOLDER/g' \
		-e "s/(set\(${VERSION_VAR}[[:space:]]+\")[^\"]+(\")/\\1${VERSION}\\2/" \
		-e 's/PLACEHOLDER/"0.0.0-local"/g' \
		"${CMAKE_FILE}"

	# Update the SHA256 checksum string in the cmake file.
	sed -z -i -E \
		"s/(set\(${CHECKSUM_VAR}[[:space:]]+\"SHA256=)[a-fA-F0-9]+(\")/\\1${SHA256}\\2/" \
		"${CMAKE_FILE}"

	echo "Updated ${CMAKE_FILE}"
}

# Update the container plugin version and per-architecture SHA256 hashes.
#
# Usage: update_container_plugin_dep <version>
update_container_plugin_dep() {
	local VERSION="$1"
	local CMAKE_FILE="${REPO_ROOT}/CMakeLists.txt"
	local BASE_URL="https://download.falco.org/plugins/stable"

	echo "Container plugin version: ${VERSION}"

	local SHA256_X86_64
	SHA256_X86_64="$(sha256_of_url "${BASE_URL}/container-${VERSION}-linux-x86_64.tar.gz")"
	echo "  SHA256 (x86_64):  ${SHA256_X86_64}"
	local SHA256_AARCH64
	SHA256_AARCH64="$(sha256_of_url "${BASE_URL}/container-${VERSION}-linux-aarch64.tar.gz")"
	echo "  SHA256 (aarch64): ${SHA256_AARCH64}"

	# note: in the following `sed` expressions, `-z` is required in order for `[[:space:]]+` to span across newlines.

	# Update `CONTAINER_VERSION`.
	sed -z -i -E \
		"s/(set\(CONTAINER_VERSION[[:space:]]+\")[^\"]+(\")/\\1${VERSION}\\2/" \
		"${CMAKE_FILE}"

	# Update the `x86_64` `CONTAINER_HASH` (the one right after `STREQUAL "x86_64"`).
	sed -z -i -E \
		"s/(STREQUAL \"x86_64\"\)[[:space:]]+set\(CONTAINER_HASH[[:space:]]+\")[a-fA-F0-9]+(\")/\\1${SHA256_X86_64}\\2/" \
		"${CMAKE_FILE}"

	# Update the `arm64` `CONTAINER_HASH` (the one right after `else() # arm64`).
	sed -z -i -E \
		"s/(else\(\)[[:space:]]+# arm64[[:space:]]+set\(CONTAINER_HASH[[:space:]]+\")[a-fA-F0-9]+(\")/\\1${SHA256_AARCH64}\\2/" \
		"${CMAKE_FILE}"

	echo "Updated ${CMAKE_FILE}"
}

# Update the rules version and SHA256 checksum.
#
# Usage: update_rules_dep <version>
update_rules_dep() {
	local VERSION="$1"
	local CMAKE_FILE="${REPO_ROOT}/cmake/modules/rules.cmake"
	local TAG="falco-rules-${VERSION}"

	echo "Rules version: ${TAG}"

	local SHA256
	SHA256="$(sha256_of_url "https://download.falco.org/rules/${TAG}.tar.gz")"
	echo "  SHA256: ${SHA256}"

	# note: in the following `sed` expressions, `-z` is required in order for `[[:space:]]+` to span across newlines.

	# Update `FALCOSECURITY_RULES_FALCO_VERSION`.
	sed -z -i -E \
		"s/(set\(FALCOSECURITY_RULES_FALCO_VERSION[[:space:]]+\")[^\"]+(\")/\\1${TAG}\\2/" \
		"${CMAKE_FILE}"

	# Update `FALCOSECURITY_RULES_FALCO_CHECKSUM`.
	sed -z -i -E \
		"s/(set\(FALCOSECURITY_RULES_FALCO_CHECKSUM[[:space:]]+\"SHA256=)[a-fA-F0-9]+(\")/\\1${SHA256}\\2/" \
		"${CMAKE_FILE}"

	echo "Updated ${CMAKE_FILE}"
}

[[ $# -ne 2 ]] && usage
SUBCMD="$1"
VERSION="$2"

case "${SUBCMD}" in
drivers)
	update_libs_or_drivers_dep \
		"${REPO_ROOT}/cmake/modules/driver.cmake" \
		"${VERSION}" \
		"DRIVER_REPO" \
		"DRIVER_VERSION" \
		"DRIVER_CHECKSUM"
	;;
libs)
	update_libs_or_drivers_dep \
		"${REPO_ROOT}/cmake/modules/falcosecurity-libs.cmake" \
		"${VERSION}" \
		"FALCOSECURITY_LIBS_REPO" \
		"FALCOSECURITY_LIBS_VERSION" \
		"FALCOSECURITY_LIBS_CHECKSUM"
	;;
container)
	update_container_plugin_dep "${VERSION}"
	;;
rules)
	update_rules_dep "${VERSION}"
	;;
*)
	usage
	;;
esac
