#!/usr/bin/sh

# Script called by qubesbuilder.ProcessGithubCommand for handling "Upload"
# command
#
# First argument is expected to be a command file path, already
# verified against trusted keys set.
# Second argument is a key fingerprint used to sign the command

if [ $# -lt 2 ]; then
    echo "Usage: $0 <command-file> <key-fingerprint>" >&2
    exit 1
fi

command_file="$1"
signer_fpr="$2"

scripts_dir="/usr/local/lib/qubes-builder-github"

# shellcheck source=lib/functions.sh
. "$scripts_dir/functions.sh"

read -r action component commit_sha release_name repo_name dists_and_end \
        < "$command_file"

if [ "x$action" != "xUpload" ]; then
    echo "Invalid action" >&2
    exit 1
fi

case "${component}" in
    *[/.$IFS]*)
        echo "Forbidden character in component name" >&2
        exit 1
        ;;
    "")
        echo "Empty component name" >&2
        exit 1
        ;;
esac

case "${dists_and_end}" in
    *repo)
        # ok
        ;;
    *)
        echo "Missing 'repo' and the command end" >&2
        exit 1
        ;;
esac

if [ "x${component}" = "xlinux-template-builder" ]; then
    if [ "x$repo_name" != "xtemplates-itl" ] && [ "x$repo_name" != "xtemplates-community" ]; then
        echo "Unsupported target repo" >&2
        exit 1
    fi
elif [ "x$repo_name" != "xcurrent" ] && [ "x$repo_name" != "xsecurity-testing" ]; then
    echo "Unsupported target repo" >&2
    exit 1
fi

# enable logging (use qrexec policy to redirect to the right VM)
export QUBES_BUILD_LOG_CMD="qrexec-client-vm 'dom0' qubesbuilder.BuildLog"

upload_for_release() {
    local_config_release_name="$1"
    local_builder_dir="$2"

    if [ "$local_config_release_name" != "$release_name" ]; then
        return
    fi

    if ! [ -d "$local_builder_dir/qubes-src/$component" ]; then
        echo "Component $component not found in $local_builder_dir" >&2
        # maybe it's in another VM?
        return 0
    fi

    # for templates verify for each separately
    if [ "$component" != "linux-template-builder" ]; then
        actual_commit_sha=$(git -C "$local_builder_dir/qubes-src/$component" rev-parse HEAD)
        if [ "x$commit_sha" != "x$actual_commit_sha" ]; then
            echo "Repository have changed in the meantime (current: $actual_commit_sha)" >&2
            return 1
        fi
    fi

    allowed_dists=$(get_allowed_dists "$local_builder_dir" "$signer_fpr")

    # remove any override from previous iteration
    unset DIST_DOM0

    # if no specific distribution was requested, upload all of them, unless template
    if [ "$component" != "linux-template-builder" ] && \
            [ "x$dists_and_end" = "xrepo" ]; then
        if [ "${allowed_dists% dom0}" = "$allowed_dists" ]; then
            # exclude dom0
            export DIST_DOM0=""
        fi
        DISTS_VM="${allowed_dists% dom0}" \
        COMPONENTS="$component" \
        MAKEREPO=1 UPLOAD=0 \
        "$local_builder_dir/scripts/make-with-log" \
            "update-repo-$repo_name" &&
        DISTS_VM="${allowed_dists% dom0}" \
        COMPONENTS="$component" \
        MAKEREPO=0 UPLOAD=1 \
        "$local_builder_dir/scripts/make-with-log" \
            "update-repo-$repo_name"
        return $?
    fi

    # otherwise, process repositories list
    requested_dists_dom0=
    requested_dists_vm=
    supported_dists_dom0=$(make --no-print-directory -C "$local_builder_dir" \
            get-var GET_VAR=DIST_DOM0)
    if [ "$component" = "linux-template-builder" ]; then
        # for templates force original DIST_DOM0 ...
        requested_dists_dom0="$supported_dists_dom0"
        supported_dists_dom0=
        # ... and DISTS_VM including flavors
        supported_dists_vm="${allowed_dists% dom0}"
    else
        # otherwise resolve aliases and cut out flavors
        supported_dists_vm=$(DISTS_VM="${allowed_dists% dom0}" \
                make --no-print-directory -C "$local_builder_dir" \
                get-var GET_VAR=DISTS_VM_NO_FLAVOR)
    fi
    # exclude dom0 if not allowed
    if [ "${allowed_dists% dom0}" = "$allowed_dists" ]; then
        supported_dists_dom0=
    fi
    IFS=' '
    for dist_pair in $dists_and_end; do
        package_set=${dist_pair%%-*}
        dist=${dist_pair#*-}
        if [ "x$package_set" = "xdom0" ]; then
            if echo " $supported_dists_dom0 " | grep -q " $dist "; then
                requested_dists_dom0="$requested_dists_dom0 $dist"
            fi
            # don't fail otherwise - maybe builder in other VM will handle it
        elif [ "x$package_set" = "xvm" ]; then
            if echo " $supported_dists_vm " | grep -q " $dist "; then
                # for templates verify its version here
                if [ "$component" = "linux-template-builder" ]; then
                    template_name=$(DISTS_VM="$dist" make -s -C "$local_builder_dir" \
                        template-name)
                    build_version=$(cat \
                        "$local_builder_dir/qubes-src/linux-template-builder/version")
                    build_timestamp=$(cat \
                        "$local_builder_dir/qubes-src/linux-template-builder/build_timestamp_$template_name")
                    if [ "$commit_sha" != "$build_version-$build_timestamp" ]; then
                        echo "Different template was built in the meantime (current: $build_version-$build_timestamp)" >&2
                        return 1
                    fi
                fi
                requested_dists_vm="$requested_dists_vm $dist"
            fi
            # don't fail otherwise - maybe builder in other VM will handle it
        elif [ "x$dist_pair" = "xrepo" ]; then
            # end processing here
            break
        fi
    done

    # strip leading spaces
    read -r requested_dists_vm <<EOF
$requested_dists_vm
EOF
    read -r requested_dists_dom0 <<EOF
$requested_dists_dom0
EOF

    if [ -n "$requested_dists_vm$requested_dists_dom0" ]; then
        COMPONENTS="$component" \
        DISTS_VM="$requested_dists_vm" \
        DIST_DOM0="$requested_dists_dom0" \
        MAKEREPO=1 UPLOAD=0 \
        "$local_builder_dir/scripts/make-with-log" \
            "update-repo-$repo_name" &&
        COMPONENTS="$component" \
        DISTS_VM="$requested_dists_vm" \
        DIST_DOM0="$requested_dists_dom0" \
        MAKEREPO=0 UPLOAD=1 \
        "$local_builder_dir/scripts/make-with-log" \
            "update-repo-$repo_name"
        return $?
    fi
}

execute_in_each_builder upload_for_release
