#!/bin/bash
# Copyright 2021 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0

set -euo pipefail

if [ "$#" -ne 1 ]; then
     echo "Usage: $0 \$GOYAML_V3_SHA"
     exit 1
 fi

if [ "$(git branch --show-current)" == "master" ]; then
  echo "You must be on a branch to use this script."
  exit 1
fi

blue=$(tput setaf 4)
normal=$(tput sgr0)

# This should be the version of go-yaml v3 used by kubectl
 # In the original fork, this is 496545a6307b2a7d7a710fd516e5e16e8ab62dbc
 export GOYAML_SHA=$1
 export GOYAML_REF="goyaml-$GOYAML_SHA"

# The PRs we need to cherry-pick onto the above commit
declare -r GO_YAML_PR=753
declare -r KUSTOMIZE_PR=4004

REPO_ROOT=$(git rev-parse --show-toplevel)
declare -r REPO_ROOT
declare -r REBASEMAGIC="${REPO_ROOT}/.git/rebase-apply"

function explain() {
    printf "\n\n%s\n" "${blue}$1${normal}"
}

# cherry-pick REPO PR
function cherry-pick(){
  repo=$1
  pull=$2
  echo "+++ Downloading patch to /tmp/${pull}.patch (in case you need to do this again)"

  curl -o "/tmp/${pull}.patch" -sSL "${repo}/pull/${pull}.patch"
  echo
  echo "+++ About to attempt cherry pick of PR. To reattempt:"
  echo "  $ git am -x -X subtree=kyaml/internal/forked/github.com/go-yaml/yaml -3 /tmp/${pull}.patch"
  echo
  git am -3 "/tmp/${pull}.patch" || {
    conflicts=false
    while unmerged=$(git status --porcelain | grep ^U) && [[ -n ${unmerged} ]] \
      || [[ -e "${REBASEMAGIC}" ]]; do
      conflicts=true # <-- We should have detected conflicts once
      echo
      explain "+++ Conflicts detected:"
      echo
      (git status --porcelain | grep ^U) || echo "!!! None. Did you git am --continue?"
      echo
      explain "+++ Please resolve the conflicts in another window (and remember to 'git add / git am --continue')"
      read -p "+++ Proceed (anything but 'y' aborts the cherry-pick)? [y/n] " -r
      echo
      if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then
        explain "Aborting." >&2
        exit 1
      fi
    done

    if [[ "${conflicts}" != "true" ]]; then
      explain "!!! git am failed, likely because of an in-progress 'git am' or 'git rebase'"
      exit 1
    fi
  }

  # remove the patch file from /tmp
  rm -f "/tmp/${pull}.patch"
}

subtree_commit_flag=""

explain "Removing the fork's tree from git, if it exists. We'll write over this commit in a moment, but \`read-tree\` requires a clean directory."
if [[ $(find  kyaml/internal/forked/github.com/go-yaml/yaml -type f -delete) ]]; then
  git commit --all -m "Temporarily remove go-yaml fork"
  subtree_commit_flag="--amend"
fi

explain "Fetching the version of go-yaml used by kubectl. Tag it more explicitly in case of conflicts with commits local to this repo."
git fetch --depth=1 https://github.com/go-yaml/yaml.git "$GOYAML_SHA:$GOYAML_REF"

explain "Inserting the content we just pulled as a subtree of this repository and squash the changes into the last commit."
git read-tree --prefix=kyaml/internal/forked/github.com/go-yaml/yaml/ -u "$GOYAML_REF"
git commit $subtree_commit_flag --all -m "Internal copy of go-yaml at $GOYAML_SHA"

explain "Subtree creation successful."

explain "Cherry-picking the commits from our go-yaml/yaml PR"
cherry-pick https://github.com/go-yaml/yaml $GO_YAML_PR

explain "Converting module to be internal."
find kyaml/internal/forked/github.com/go-yaml/yaml -name "*.go" -type f | xargs sed -i '' s+"gopkg.in/yaml.v3"+"sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/go-yaml/yaml"+g
rm kyaml/internal/forked/github.com/go-yaml/yaml/go.mod
git commit --all -m "Internalize forked code"

# This is only necessary in the initial forking of the code
# explain "Cherry-picking the commits from our test fixes in Kustomize PR"
# cherry-pick https://github.com/kubernetes-sigs/kustomize $KUSTOMIZE_PR

explain "SUCCEEDED."
exit 0
