#!/usr/bin/bash

# Copies patches from QT_GIT_REPOS_DIR to default
# variant of specified repo and updates sources and checksums

#set -euxo pipefail
set -e # abort on first error
shopt -s nullglob
source /usr/share/makepkg/util/message.sh
colorize

if ! [[ $1 ]]; then
    echo 'No Qt repo specified - must be specified like eg. base or multimedia.'
    echo "Usage: $0 repo [branch=\$pkgver-\$variant] [variant=mingw-w64] [qtver=qt5] [tag=v\$pkgver]"
    echo "Note: DEFAULT_PKGBUILDS_DIR and QT_GIT_REPOS_DIR must point to directories containing PKGBUILDs and the Qt repos."
    exit -1
fi

pkgbuildsdirs=()
if [[ $DEFAULT_PKGBUILDS_DIR ]]; then
    # split colon separated path
    OIFS=$IFS
    IFS=':'
    for dir in $DEFAULT_PKGBUILDS_DIR; do
        pkgbuildsdirs+=("$dir")
    done
    IFS=$OIFS
else
    pkgbuildsdirs+=("$PWD/pkgbuilds")
fi

qtver="${4:-qt5}"
pkg="$qtver-$1"
repo="qt$1"
branch="${2}"
variant="${3:-mingw-w64}"
tag=$5

# find dest dir
pkgdir=
for dir in "${pkgbuildsdirs[@]}"; do
    for _pkgdir in "$pkg" "qt5"; do
        dest="${dir}/${_pkgdir}/${variant}"
        pkgdir=$_pkgdir
        [[ -d $dest ]] && break 2 || dest=
    done
done
if ! [[ $dest ]]; then
    warning "\$DEFAULT_PKGBUILDS_DIR/$pkg/${variant} or \$DEFAULT_PKGBUILDS_DIR/qt5/${variant} is no directory - skipping repository $repo."
    exit 0
fi

# find repo dir
wd="${QT_GIT_REPOS_DIR}/${repo}"
if ! [[ -d $wd ]]; then
    error "\$QT_GIT_REPOS_DIR/$repo is no directory."
    exit -2
fi

pkgbuild_path=$dest/PKGBUILD
if ! [[ -f $pkgbuild_path ]]; then
    warning "PKGBUILD does not exist in \"$dest\" - skipping directory"
    exit 0
fi
template=$pkgbuild_path.sh.ep has_template=
[[ -f $template ]] && has_template=1

source "$pkgbuild_path"
tag=${tag:-v$pkgver}
tag=${tag%+kde+*}

new_sources=()
new_md5sums=()
file_index=0
for source in "${source[@]}"; do
    [ "${source: -6}" != .patch ] && \
        new_sources+=("$source") \
        new_md5sums+=("${sha256sums[$file_index]}")
    file_index=$((file_index + 1))
done

if [[ $pkgdir != qt5 ]]; then
    patches=("$dest"/*.patch)
    for patch in "${patches[@]}"; do
        [[ -f $patch ]] && rm "$patch"
    done
fi

pushd "$wd" > /dev/null
git status # do some Git stuff just to check whether it is a Git repo
if ! [[ $branch ]]; then
    branch="${pkgver}-${variant}"
fi
if ! git checkout "${branch}"; then
    msg2 "No patches required for $1, skipping."
    exit 0
fi
msg2 "Exporting patches for branch '$branch' (based on '$tag')"
git format-patch "$tag" --output-directory "$dest"
new_patches=("$dest"/*.patch)
also_covered_variants=none # for sake of simplicity: use same set of patches also for android/static-compat/wasm packages
more_covered_variants=none
[[ $variant == mingw-w64 ]] && also_covered_variants=android- more_covered_variants=static-compat even_more_covered_variants=wasm
for other_variant_dir in "$dest/../$variant"?* "$dest/../$also_covered_variants"?* "$dest/../$more_covered_variants"* "$dest/../$even_more_covered_variants"*; do
    [[ -d $other_variant_dir ]] || continue
    find "$other_variant_dir" -iname '*.patch' -delete
    if [[ ${#new_patches[@]} -gt 0 ]]; then
        ln --verbose --symbolic --relative --target-directory="$other_variant_dir" "${new_patches[@]}"
    fi
done
popd > /dev/null

# skip if building all Qt modules in one package (currently used for Android target)
[[ $pkgdir == qt5 ]] && exit 0

# skip if a template file is present (then the patch list is generated by the template
# system)
[[ -f $has_template ]] && exit 0

for patch in "${new_patches[@]}"; do
    new_sources+=("$patch")
    sum=$(sha256sum "$patch")
    new_md5sums+=(${sum%% *})
done

# preserve first src line to keep variables unevaluated
newsrc=$(grep 'source=(' "$pkgbuild_path")
[[ $newsrc ]] || newsrc="source=(${new_sources[0]}"
[ "${newsrc: -1:1}" == ')' ] && newsrc="${newsrc: 0:-1}" # truncate trailing )
for source in "${new_sources[@]:1}"; do
    newsrc+="\n        '${source##*/}'"
done
newsrc+=')'

newsums="sha256sums=('${new_md5sums[0]}'"
for sum in "${new_md5sums[@]:1}"; do
    newsums+="\n            '${sum}'"
done
newsums+=')'

# apply changes
mv "$pkgbuild_path" "$pkgbuild_path.bak"
awk -v newsrc="$newsrc" -v newsums="$newsums" '
    /^[[:blank:]]*source(_[^=]+)?=/,/\)[[:blank:]]*(#.*)?$/ {
        if (!s) {
            print newsrc
            s++
        }
        next
    }
    /^[[:blank:]]*(md|sha)[[:digit:]]+sums(_[^=]+)?=/,/\)[[:blank:]]*(#.*)?$/ {
        if (!w) {
            print newsums
            w++
        }
        next
    }

    1
    END {
        if (!s) {
            print newsrc
        }
        if (!w) {
            print newsums
        }
    }
' "$pkgbuild_path.bak" > "$pkgbuild_path"
