#!/usr/bin/env bash

# Copyright 2025 The KCP 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.

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

REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)
DEFAULTRESTMAPPER_FILEPATH="${DEFAULTRESTMAPPER_FILEPATH:-$( go list -m -json k8s.io/apimachinery | jq -r .Dir )/pkg/api/meta/restmapper.go}"
DEFAULTRESTMAPPER_PATCH_FILEPATH="${DEFAULTRESTMAPPER_PATCH_FILEPATH:-${REPO_ROOT}/pkg/reconciler/dynamicrestmapper/defaultrestmapper_kcp.go}"

function usage {
    echo "gen-patch-defaultrestmapper copies upstream's DefaultRESTMapper,"
    echo "makes the changes needed by our DynamicRESTMapper, and stores"
    echo "the result in ${DEFAULTRESTMAPPER_PATCH_FILEPATH}."
    echo
    echo "By default, gen-patch-defaultrestmapper tries to look for"
    echo "restmapper.go in:"
    echo
    printf "\t%s,\n" "${DEFAULTRESTMAPPER_FILEPATH}"
    echo
    echo "as detected by 'go list -m -json k8s.io/apimachinery'."
    echo "If you wish to use a different path, pass it in through"
    echo "DEFAULTRESTMAPPER_FILEPATH environment variable."
    echo
    echo "Usage:"
    echo
    printf "\t%s\n" "${0}"
    exit 0
}

# Script input validation.

[[ $# != 0 ]] && usage
[[ -f "${DEFAULTRESTMAPPER_FILEPATH}" ]] || { echo "Error: ${DEFAULTRESTMAPPER_FILEPATH} (from DEFAULTRESTMAPPER_FILEPATH) is not a file" 1>&2 ; exit 1 ; }
touch "${DEFAULTRESTMAPPER_PATCH_FILEPATH}"
[[ -f "${DEFAULTRESTMAPPER_PATCH_FILEPATH}" ]] || { echo "Error: ${DEFAULTRESTMAPPER_PATCH_FILEPATH} (from DEFAULTRESTMAPPER_PATCH_FILEPATH) is not a file" 1>&2 ; exit 1 ; }

# File generation.

# First, we generate the preamble with our package name, and
# paste upstream's defaultrestmapper.go contents, starting right
# after its `package meta` declaration.

sed "s/YEAR/$(date +'%Y')/" "${REPO_ROOT}/hack/boilerplate/boilerplate.go.txt" > "${DEFAULTRESTMAPPER_PATCH_FILEPATH}"
cat >> "${DEFAULTRESTMAPPER_PATCH_FILEPATH}" << Header_EOF

package dynamicrestmapper

// Code generated by hack/gen-patch-defaultrestmapper.sh
// Original file in k8s.io/apimachinery/pkg/api/meta/restmapper.go.

// We need this DefaultRESTMapper fork to be able to modify its
// internal mappings, to support update and deletion operations.
// These are implemented separately, in defaultrestmapper_mutable.go.

import "k8s.io/apimachinery/pkg/api/meta" // Import the source package of the original file.

Header_EOF

awk '/^package meta$/ {flag=1; next} flag' "${DEFAULTRESTMAPPER_FILEPATH}" >> "${DEFAULTRESTMAPPER_PATCH_FILEPATH}"

# Next, we need to replace symbols that were local to the meta
# package with their package-qualified names and fix the imports
# in the resulting file.

# This is the list of all symbols that need to be referenced inside
# the k8s.io/apimachinery/pkg/api/meta package.
#
# Please keep it up-to-date and sorted.
symbols_from_meta_pkg=(
    AmbiguousResourceError
    NoKindMatchError
    NoResourceMatchError
    ResettableRESTMapper
    RESTMapper
    RESTMapping
    RESTScope
    RESTScopeName
    RESTScopeNameNamespace
    RESTScopeNameRoot
)

for sym in ${symbols_from_meta_pkg[@]}; do
    gofmt -w -r "${sym} -> meta.${sym}" "${DEFAULTRESTMAPPER_PATCH_FILEPATH}"
done

# Inform the caller if there were changes. Something could have broken.

git diff --quiet -- "${DEFAULTRESTMAPPER_PATCH_FILEPATH}" || {
    echo "Warning: ${DEFAULTRESTMAPPER_PATCH_FILEPATH} was modified." 1>&2
    echo "Warning: Please inspect the changes before continuing. Run:" 1>&2
    printf "\n\tgit diff -- %s\n\n" "${DEFAULTRESTMAPPER_PATCH_FILEPATH}" 1>&2
    exit 0
}
