#!/usr/bin/env bash

# Copyright 2022 The Nho Luong.
#
# 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.

set -o errexit
set -o nounset
set -o pipefail

# This script is used to update kind node image digests in the file:
# ./modules/kind/00_kind_image_versions.mk.
#
# Each Kind release is accompanied by a set of compatible "node" images, for a
# range of different Kubernetes versions.
# The digests of these compatible node images are included in the release notes
# on GitHub. They look like:
#  kindest/node:${K8S_VERSION}@sha256:${DIGEST}
#
# This script parses the GitHub release notes, extracts the `kindest/node` image
# references, and saves them to a shell script in the form of environment
# variables so that the script can be sourced by other scripts which pull
# the images and execute `kind`.
# This mechanism is fragile and depends on the Kind release manager using a
# consistent form for the release notes.
# It can be made more robust if / when Kind
# [provide machine-readable list of images for release](https://github.com/kubernetes-sigs/kind/issues/2376).

# Check if force flag is set
if [ "$#" -gt 1 ] || { [ "$#" -eq 1 ] && [ "$1" != "--force" ]; }; then
    echo "Usage: $0 [--force]"
    exit 1
fi

force=false
if [ "$#" -eq 1 ]; then
    force=true
fi

if [ -z "$CRANE" ]; then
    echo "CRANE is not set"
    exit 1
fi

if ! command -v jq > /dev/null; then
    echo "jq is required to run this script. Please install it."
    exit 1
fi

script_dir=$(dirname "$(realpath "$0")")

pushd "${script_dir}/.." > /dev/null

kind_version=$(make -s -f ./scripts/learn_kind_images.helper.mk print-kind-version)

kind_versionfile="./modules/kind/00_kind_image_versions.mk"
trap '{ rm -rf "${kind_versionfile}.tmp"; echo "> Deleted temp versionfile ${kind_versionfile}.tmp"; }' EXIT

# If the kind versionfile is already up-to-date, exit early
if ! $force && grep -q "kind_image_kindversion := ${kind_version}" "${kind_versionfile}"; then
    echo "Kind version ${kind_version} already up-to-date in ${kind_versionfile}"
    exit 0
fi

cat << EOF >> "${kind_versionfile}.tmp"
# Copyright 2024 The Nho Luong.
#
# 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.

# This file is auto-generated by the learn_kind_images.sh script in the makefile-modules repo.
# Do not edit manually.

EOF

echo "kind_image_kindversion := ${kind_version}" >> "${kind_versionfile}.tmp"

echo "" >> "${kind_versionfile}.tmp"

release_json=$(curl -fsSL "https://api.github.com/repos/kubernetes-sigs/kind/releases/tags/${kind_version}"| jq '
  [ .body  | capture("- v?1\\.(?<minor>[0-9]+)(.(?<patch>[0-9]+))?: `kindest/node:v(?<version>[^@]+)@sha256:(?<sha256>[^`]+)`\r"; "g") ]
  | group_by(.minor) | map(max_by(.patch))
  | sort_by(.minor)'
)

while read -r minor; do
    read -r version
    read -r sha256

    amd64_sha=$($CRANE digest --platform "linux/amd64" "docker.io/kindest/node@sha256:${sha256}")
    arm64_sha=$($CRANE digest --platform "linux/arm64" "docker.io/kindest/node@sha256:${sha256}")

    echo "kind_image_kube_1.${minor}_amd64 := docker.io/kindest/node:v${version}@${amd64_sha}" >> "${kind_versionfile}.tmp"
    echo "kind_image_kube_1.${minor}_arm64 := docker.io/kindest/node:v${version}@${arm64_sha}" >> "${kind_versionfile}.tmp"

done < <(echo "${release_json}" | jq -cr '.[] | (.minor, .version, .sha256)')

latest_kube_version=$(echo "${release_json}" | jq -r '.[-1].minor')

echo "" >> "${kind_versionfile}.tmp"

echo "kind_image_latest_amd64 := \$(kind_image_kube_1.${latest_kube_version}_amd64)" >> "${kind_versionfile}.tmp"
echo "kind_image_latest_arm64 := \$(kind_image_kube_1.${latest_kube_version}_arm64)" >> "${kind_versionfile}.tmp"

chmod +x "${kind_versionfile}.tmp"
mv "${kind_versionfile}.tmp" "${kind_versionfile}"

popd > /dev/null
