#!/bin/bash
# A tool for bumping the revision number of dependent ports
# Author: Marin Saric <marin.saric@gmail.com>

if [[ "$1" == "" ]]; then
    cat <<EOF
Usage:
   bump_dep_revs.sh port-name

   This tool will generate a patchfile that will bump up the revision of all
   the portfiles that depend on the port port-name.
EOF
    exit 1
fi

port_name="$1"

ports_dir=$( cd $( port dir coreutils ) && cd ../.. && pwd )

if [[ "$( port dir ${port_name} )" == "" ]]; then
    echo "Error: Can't find the port ${port_name}" >&2
    exit 1
fi

dependent_portfiles=$( find "${ports_dir}" -name Portfile \
    | xargs grep -l -w port:"${port_name}" )

if [[ "${dependent_portfiles}" == "" ]]; then
    echo "Done. No dependencies for ${port_name}" >&2
    exit 0
fi

has_field() {
    [[ x"$1" == x"" || x"$2" == x"" ]] && echo "ERROR" >&2 && return 1

    local portfile="$1"
    local field_name="$2"
    local has_rev=$( cat "$portfile" | \
	awk '{ if ($1 == "'"${field_name}"'") { print "yes" } }' )
    [[ x"${has_rev}" == x"yes" ]]
}

bump_existing_revision() {
    [[ x"$1" == x"" ]] && echo "ERROR" >&2 && return 1
    local portfile="$1"
    awkcode=$( cat <<"EOF"
{
    if ($1 == "revision") {
        rev_num = $2;
        rev_pos = index($0, rev_num);
        print substr($0, 1, rev_pos - 1)""(rev_num + 1);
    } else {
        print $0;
    }
}
EOF
    )

    cat "$portfile" | awk "$awkcode"
}

add_revision_tag() {
    [[ x"$1" == x"" ]] && echo "ERROR" >&2 && return 1
    local portfile="$1"

    local field_to_emulate="version"

    if ! has_field "$portfile" version; then
	field_to_emulate="name"
	if ! has_field "$portfile" name; then
	    echo "ERROR: Port $portfile does not have a name field" >&2
	    return 1
	fi
    fi

    awkcode=$( cat <<"EOF"
{
    if ($1 == field_name) {
         param_2 = $2;
         param_2_pos = index($0, param_2);
         num_spaces = param_2_pos - length(field_name) - 1;
         space_delta = length(field_name) - length("revision");
         num_spaces = num_spaces + space_delta;
         if (num_spaces < 1) num_spaces = 1;
         spaces = "";
         for (i = 0; i < num_spaces; ++i) spaces = spaces" ";
         print $0;
         print "revision"spaces"2";
    } else {
         print $0;
    }
}
EOF
    )
    cat "$portfile" | awk "$awkcode" field_name="${field_to_emulate}"
}

bump_port_revision() {
    [[ x"$1" == x"" ]] && echo "ERROR" >&2 && return 1
    local portfile="$1"

    if has_field "$portfile" revision; then
	bump_existing_revision "$portfile"
    else
	add_revision_tag "$portfile"
    fi
}

for portfile in ${dependent_portfiles}; do
    port_name_dir=$( basename $( dirname "${portfile}" ) )
    port_category_dir=$( basename $( dirname $( dirname "${portfile}" ) ) )
    port_namecat_dir="${port_category_dir}/${port_name_dir}"

    tmpdir=$( mktemp -d )
    tmp_port_dir="${tmpdir}/${port_namecat_dir}"

    mkdir -p "${tmp_port_dir}"
    cp "${portfile}" "${tmp_port_dir}/Portfile.orig"

    bump_port_revision "${portfile}" >"${tmp_port_dir}/Portfile"
    cd "${tmpdir}" && \
	diff -u "${port_namecat_dir}/Portfile.orig" "${port_namecat_dir}/Portfile"

    rm "${tmp_port_dir}"/*
    rmdir "${tmpdir}/${port_namecat_dir}"
    rmdir "${tmpdir}/${port_category_dir}"
    rmdir "${tmpdir}"
done