#!/usr/bin/env bash

set -Eeuo pipefail

# shellcheck disable=SC1091,SC1090
source "$(dirname "${BASH_SOURCE[0]}")/../lib/__sources__.bash"

function add_component {
  local component image_ref parameters git_repo revision dockerfile
  component=${2}
  image_ref=${3}

  echo "Adding ${component} (${image_ref})"

  parameters="$(cosign download attestation "${image_ref}" | jq -r '.payload' | base64 -d | jq -c '.predicate.invocation.parameters')"
  git_repo="$(echo "${parameters}" | jq -r '."git-url"')"
  revision="$(echo "${parameters}" | jq -r ".revision")"
  dockerfile="$(echo "${parameters}" | jq -r ".dockerfile")"

  cat << EOF | yq write --inplace --script - "$1"
- command: update
  path: spec.components[+]
  value:
    name: "${component}"
    containerImage: "${image_ref}"
    source:
      git:
        url: "${git_repo}"
        revision: "${revision}"
        dockerfileUrl: "${dockerfile}"
EOF
}

function create_component_snapshot {
  local snapshot_file so_short_version so_version so_semversion serving_tag serving_version_dotted serving_version tmp_catalog_dir max_ocp_version latest_index_image
  snapshot_file="${1}/override-snapshot.yaml"

  serving_tag="$(metadata.get dependencies.serving)"
  serving_version_dotted="${serving_tag/knative-v/}" # -> 1.15
  serving_version="${serving_version_dotted/./}"
  so_branch="$(sobranch --upstream-version "${serving_version_dotted}")"
  so_version="$(get_app_version_from_tag "${serving_tag}")"
  so_semversion="$(metadata.get project.version)"
  so_short_version=${so_semversion/./} # 1.36.0 -> 136.0
  so_short_version=${so_short_version%.*} # 136.0 -> 136

  cat > "${snapshot_file}" <<EOF
apiVersion: appstudio.redhat.com/v1alpha1
kind: Snapshot
metadata:
  name: serverless-operator-${so_short_version}-override-snapshot
  labels:
    test.appstudio.openshift.io/type: override
    application: serverless-operator-${so_short_version}
    branch: ${so_branch}
spec:
  application: serverless-operator-${so_short_version}
EOF

  tmp_catalog_dir=$(mktemp -d)
  max_ocp_version="$(metadata.get requirements.ocpVersion.list[-1])"
  max_ocp_version=${max_ocp_version/./}
  latest_index_image="${registry_quay}-fbc-${max_ocp_version}/serverless-index-${so_short_version}-fbc-${max_ocp_version}:latest"

  # get catalog from latest index, so we can get the referenced images from there
  opm migrate "${latest_index_image}" "${tmp_catalog_dir}" -o json

  while IFS= read -r image_ref; do
    # shellcheck disable=SC2053

    if  [[ $image_ref =~ $registry_redhat_io ]]; then
      image=${image_ref##*/} # Get image name after last slash
      image_sha=${image_ref##*@} # Get SHA of image
      image=${image%@*} # Remove sha
      image=${image/-rhel[0-9]/} # Remove -rhelX part

      component_image_ref="${registry_quay}/${image}@${image_sha}"

      if [[ $image == "serverless-operator-bundle" ]]; then
        # bundle component is named in konflux serverless-bundle-<version>

        component_name="serverless-bundle-${so_short_version}"
        component_image_ref="${registry_quay}/serverless-bundle@${image_sha}"
      elif [[ $image =~ serverless ]]; then
        component_name="${image}-${so_short_version}"
      else
        component_name="${image}-${serving_version}"
      fi

      add_component "${snapshot_file}" "${component_name}" "${component_image_ref}"
    fi
  done <<< "$(jq -r '. | select(.name == "serverless-operator.v'${so_semversion}'") | .relatedImages[].image' "${tmp_catalog_dir}/serverless-operator/catalog.json" | sort | uniq)"
  # ^ we take the images from the catalogs relatedImages section for the given SO version. We could also extract the bundle image from the catalog (jq -r '. | select(.name == "serverless-operator.v'${so_semversion}'") | .image')
  # and extract the CSV from there and use the CSVs relatedImages section.

  append_hash_to_snapshot_name "${snapshot_file}"

  rm -rf "${tmp_catalog_dir}"
}

function create_fbc_snapshots {
  local rootdir snapshot_dir so_short_version so_branch serving_tag
  rootdir="$(dirname "$(dirname "$(dirname "$(realpath "${BASH_SOURCE[0]}")")")")"
  snapshot_dir="${1}"

  serving_tag="$(metadata.get dependencies.serving)"
  so_branch="$(sobranch --upstream-version "${serving_tag/knative-v/}")"
  so_short_version="$(metadata.get project.version)"
  so_short_version=${so_short_version/./} # 1.36.0 -> 136.0
  so_short_version=${so_short_version%.*} # 136.0 -> 136

  while IFS= read -r ocp_version; do
    ocp_version=${ocp_version/./}
    snapshot_file="${snapshot_dir}/override-snapshot-fbc-${ocp_version}.yaml"

    cat > "${snapshot_file}" <<EOF
apiVersion: appstudio.redhat.com/v1alpha1
kind: Snapshot
metadata:
  name: serverless-operator-${so_short_version}-fbc-${ocp_version}-override-snapshot
  labels:
    test.appstudio.openshift.io/type: override
    application: serverless-operator-${so_short_version}-fbc-${ocp_version}
    branch: ${so_branch}
spec:
  application: serverless-operator-${so_short_version}-fbc-${ocp_version}
EOF

  index_image="${registry_quay}-fbc-${ocp_version}/serverless-index-${so_short_version}-fbc-${ocp_version}"
  index_image_digest="$(skopeo inspect --retry-times=10 --no-tags docker://"${index_image}:latest" | jq -r .Digest)"
  add_component "${snapshot_file}" "serverless-index-${so_short_version}-fbc-${ocp_version}" "${index_image}@${index_image_digest}"

  append_hash_to_snapshot_name "${snapshot_file}"

  done <<< "$(yq read "${rootdir}/olm-catalog/serverless-operator/project.yaml" 'requirements.ocpVersion.list[*]')"
}

function append_hash_to_snapshot_name {
  file=${1}
  sha_sum="$(sha256sum "$file" | head -c 8)" # get first 8 chars of sha
  new_name="$(yq read "$file" metadata.name)-$sha_sum"

  yq write --inplace "$file" metadata.name "$new_name"
}

target_dir="${1:?Provide a target directory for the override snapshots as arg[1]}"
create_component_snapshot "${target_dir}"
create_fbc_snapshots "${target_dir}"
