#!/bin/sh

# Copyright (c) 2008-2012 Aleksey Cheusov <vle@gmx.net>
# All rights reserved.
#
# See LICENSE file

######################################################################

set -e
. /usr/pkg/bin/pipestatus

export LC_ALL=C

# usage: stage_init BUILD_ID
test $# -eq 1

# init
BUILD_ID="$1"
test -n "$build_start" # MUST be set in environment

packages="$pkgs_fn" # pkgs_fn - from distbb

: ${DISTBB_CONF:=/usr/pkg/etc/distbb.conf}
. "$DISTBB_CONF"
. /usr/pkg/libexec/distbb/common

mkdir -p "$MSCOMMONDIR"

if touch "$MSCOMMONDIR/check"; then
    rm "$MSCOMMONDIR/check"
else
    cat <<EOF
$MSCOMMONDIR directory is not writable or doesn't exist.
EOF
    exit 1
fi

test -n "$BUILD_ID" -a -n "$REPORTS_DIR" # who knows...
rm -rf $REPORT1_DIR
mkdir -p -m 700 $tmpdir
cp "$ICON_FILE" "$REPORT1_DIR/distbb.ico"
cp "$CSS_FILE" "$REPORT1_DIR/distbb.css"

echo "$build_start" > $build_start_fn

tmp_stderr_fn="$tmpdir/tmp_stderr"

indent2 (){
    awk '{print "  " $0}' "$@"
}

summary2PAeNA (){
    awk '
/^PKGPATH=/ { pkgpath = substr($0,9)}
/^PKGNAME=/ { pkgname = substr($0,9)}
/^ASSIGNMENTS=/ { assign = substr($0,13)}
NF == 0 {
   if (assign)
      pkgpath=pkgpath ":" assign
   print pkgpath ";" pkgname
   pkgpath = pkgname = assign = ""
}
' "$@"
}

summary2PKGPATH (){
    sed -n 's/^PKGPATH=//p' "$@"
}

# main
verbose_print "Preparations\n"

printf '' > $packages_failed_notavail_fn.tmp
printf '' > $packages_failed_scan_fn
printf '' > $packages_failed_deps_fn
printf '' > $packages_failed_fn.tmp
printf '' > $packages_built_prev_fn

printf '' > $progress_fn

######################################################################
### unpacking bootstrap
verbose_print "  removing PREFIX and unpacking bootstrap..."
if is_true "$MASTER_MODE"; then
    for s in $SLAVES; do
	eval "$TRANSPORT '$s' 'env DISTBB_CONF=$DISTBB_CONF /usr/pkg/libexec/distbb/wrapper $RMDIRS_CMD'"
	eval "$TRANSPORT '$s' 'env DISTBB_CONF=$DISTBB_CONF /usr/pkg/libexec/distbb/wrapper $EXTRACT_BOOTSTRAP_CMD'"
    done
else
    eval /usr/pkg/libexec/distbb/wrapper $RMDIRS_CMD
    eval /usr/pkg/libexec/distbb/wrapper $EXTRACT_BOOTSTRAP_CMD
fi
verbose_print "done\n"

######################################################################
### initial packages
verbose_print "  initial packages..."

cleanup_package_list (){
    awk '
    {
       sub(/#.*$/, "")
    }
    NF > 0 {
       print $1
    }' "$packages"
}

raw_packages_fn="$tmpdir/raw_packages.tmp"
if test "$packages"; then
    # remove comments and empty lines
    cleanup_package_list > "$raw_packages_fn"
else
    if is_true "$MASTER_MODE" -a -n "$TRANSPORT" -a -n "$SLAVES"; then
	slave1="$(echo $SLAVES | sed 's, .*$,,')"
	eval "$TRANSPORT '$slave1' 'env DISTBB_CONF=$DISTBB_CONF /usr/pkg/libexec/distbb/wrapper $LIST_ALL_PKGS_CMD'"
    else
	eval "/usr/pkg/libexec/distbb/wrapper $LIST_ALL_PKGS_CMD"
    fi > "$raw_packages_fn"
fi

# add extra packages to the list of packages requested by user
for p in $EXTRA_DEPS; do
    echo $p >> "$raw_packages_fn"
done

sort_uniq_inplace "$raw_packages_fn"

verbose_print "done\n"

######################################################################
### updating PKG_ALL_SUMMARY

if test -z "$skip_updating_summary"; then
    if is_true "$CROSS_COMPILE"; then
	verbose_print "  updating target pkg_all_summary..."
	eval /usr/pkg/libexec/distbb/wrapper $PKG_UPDATE_ALL_SUMMARY_CMD \
	    "$TARGET_PKG_ALL_SUMMARY" "$TARGET_PACKAGES/All"
	verbose_print "done\n"
    fi

    verbose_print "  updating pkg_all_summary..."
    eval /usr/pkg/libexec/distbb/wrapper $PKG_UPDATE_ALL_SUMMARY_CMD \
	"$PKG_ALL_SUMMARY" "$PACKAGES/All"
    verbose_print "done\n"
fi

######################################################################
### updating PKG_SRC_SUMMARY

printf '' >> "$build_src_summary_log_fn"

if test -z "$skip_updating_src_summary"; then
    if ! is_true "$MASTER_MODE"; then
	unset PSS_SLAVES || true
    fi

    # target host
    if is_true "$CROSS_COMPILE"; then
	raw_target_packages_fn="$tmpdir/raw_target_packages.tmp"
	mv "$raw_packages_fn" "$raw_target_packages_fn"

	verbose_print "  updating target pkg_src_summary..."
	set +e # workaround for buggy Korn Shell
	# ('set -e' + if + eval + false)
	if ! eval env \
	    MAKECONF="$TARGET_MAKECONF" \
	    "/usr/pkg/libexec/distbb/wrapper $TARGET_PKG_UPDATE_SRC_SUMMARY_CMD \
	    < $raw_target_packages_fn 2> $build_src_summary_log_fn"
	then
	    cat "$build_src_summary_log_fn" 1>&2
	    exit 1
	fi
	set -e
	verbose_print "done\n"

	#
	if test -s "$build_src_summary_log_fn"; then
	    echo '-----------------' >> "$build_src_summary_log_fn"
	fi

	# getting TOOL_DEPENDS from target src_summary
	runawk -f braceexpand.awk -e '
	    match($0, /^TOOLS_DEPENDS=/) {
		$0 = substr($0, RLENGTH+1)
		for (i=1; i <= NF; ++i){
		    if ($i ~ /[{]/) $i = braceexpand($i)
		    gsub(/[^ ]*:([.][.]\/[.][.]\/)?/, "", $i)
		    gsub(/ .*$/, "", $i)
		    print $i
		}
	    }' "$TARGET_PKG_SRC_SUMMARY" | sort -u > "$raw_packages_fn"
    fi

    verbose_print "  updating pkg_src_summary..."
    set +e # workaround for buggy Korn Shell
	   # ('set -e' + if + eval + false)
    if ! eval "/usr/pkg/libexec/distbb/wrapper $PKG_UPDATE_SRC_SUMMARY_CMD \
	    < $raw_packages_fn 2>> $build_src_summary_log_fn"
    then
	cat "$build_src_summary_log_fn" 1>&2
	exit 1
    fi
    set -e
    verbose_print "done\n"

    if is_true "$CROSS_COMPILE"; then
	raw_packages_fn="$raw_target_packages_fn"
    fi
fi

add_BH_prefix1 (){
    runawk -f distbb.awk -e '
/^PKGPATH=/ {
   sub(/=/, "=BH--")
   print $0
   next
}
/^PKGNAME=/ {
   sub(/=/, "=BH--")
   print $0
   next
}
{
  sub(/^TOOL_DEPENDS=/, "BUILD_DEPENDS=")
}
match($0, /^(BUILD_)?DEPENDS=/) {
   prepand_pkgpath("BH--")
}
{ print $0 }
' "$@"
}

add_BH_prefix2 (){
    runawk -f distbb.awk -e '
match($0, /^TOOL_DEPENDS=/) { prepand_pkgpath("BH--"); bdeps = substr($0, RLENGTH+1); }
match($0, /^(BUILD_)?DEPENDS=/) { tbdeps = substr($0, RLENGTH+1); }
NF == 0 {
   if (bdeps)
      print "BUILD_DEPENDS=" bdeps, tbdeps
   bdeps = tbdeps = ""
}
{ print $0 }
' "$@"
}

pkg_assignments2pkgpath "$PKG_SRC_SUMMARY" > "$pkg_src_summary_fn.tmp"
pkg_summary2bb_pkgs "$pkg_src_summary_fn.tmp" > "$pkg_src_summary_fn"
rm "$pkg_src_summary_fn.tmp"
if is_true "$CROSS_COMPILE"; then
    # build host summary
    add_BH_prefix1 "$pkg_src_summary_fn" > "$pkg_src_summary_fn.tmp"

    # target host summary
    pkg_assignments2pkgpath "$TARGET_PKG_SRC_SUMMARY" > "$pkg_src_summary_fn.tmp2"
    pkg_summary2bb_pkgs "$pkg_src_summary_fn.tmp2" > "$pkg_src_summary_fn.tmp3"
    add_BH_prefix2 "$pkg_src_summary_fn.tmp3" >> "$pkg_src_summary_fn.tmp"
    rm "$pkg_src_summary_fn.tmp3" "$pkg_src_summary_fn.tmp2"

    mv "$pkg_src_summary_fn.tmp" "$pkg_src_summary_fn"
fi

######################################################################
### packages for which pkg_src_summary failed.
verbose_print "  is there packages for which pkg_src_summary failed?..."

pkg_grep_summary -f PKGPATH,PKGNAME,ASSIGNMENTS -t strfile PKGPATH \
    "$raw_packages_fn" < "$pkg_src_summary_fn" | summary2PAeNA \
    > "$tmpdir/packages_PAeNA.tmp"
pkg_grep_summary -f PKGPATH,PKGNAME,ASSIGNMENTS -t strfile PKGPATHe \
    "$raw_packages_fn" < "$pkg_src_summary_fn" | summary2PAeNA \
    >> "$tmpdir/packages_PAeNA.tmp"
sort_uniq_inplace "$tmpdir/packages_PAeNA.tmp"

PAeNA2PA "$tmpdir/packages_PAeNA.tmp" | sort -u > "$tmpdir/packages_PA.tmp"
comm -23 "$raw_packages_fn" "$tmpdir/packages_PA.tmp" > "$packages_failed_scan_fn"

verbose_print "done\n"

printf '' > "$errors_fn"

######################################################################
### dependency graph of packages to rebuild
verbose_print "  dependency graph of packages to rebuild..."

awk '
/^PKGNAME/ {pkgbase = substr($0, 9); sub(/-[^-]*$/, "", pkgbase)}
/^PKGPATH/ {pkgpath = substr($0, 9); sub(/:.*$/, "", pkgpath)}
NF == 0 {print pkgpath "," pkgbase}
' "$pkg_src_summary_fn" > "$tmpdir/src_PABA.tmp"

summary2PKGPATH "$pkg_src_summary_fn" |
sort -u > "$tmpdir/all_src_pkgpaths.tmp"

all_deps_PAeNA_fn=$tmpdir/all_deps_PAeNA.tmp
all_bin_summary_fn=$tmpdir/all_bin_summary.tmp
if is_true "$CROSS_COMPILE"; then
    add_BH_prefix1 "$PKG_ALL_SUMMARY" > "$all_bin_summary_fn"
    add_BH_prefix2 "$TARGET_PKG_ALL_SUMMARY" >> "$all_bin_summary_fn"
else
    all_bin_summary_fn="$PKG_ALL_SUMMARY"
fi

pkg_summary2deps -Apnrsal2 -P "$tmpdir/all_src_pkgpaths.tmp" \
    "$pkg_src_summary_fn" "$all_bin_summary_fn" \
    > "$all_deps_PAeNA_fn" 2>"$tmp_stderr_fn"
if test -s "$tmp_stderr_fn"; then
    cat >> "$errors_fn" <<'EOF'
------------------
pkg_summary2deps:
EOF
    indent2 "$tmp_stderr_fn" >> "$errors_fn"
fi

/usr/pkg/libexec/distbb/pkg_summary2build_deps \
    -s "$pkg_src_summary_fn" \
    -b "$all_bin_summary_fn" \
    -r "$tmpdir/updated_PAeNA.tmp" \
    -m ${deps_graph_mode} \
    "$all_deps_PAeNA_fn" > "$tmpdir/reqd_deps_PAeNA_pre.tmp"

if test "$packages"; then
    pkg_subgraph_deps -r -f "$tmpdir/packages_PAeNA.tmp" \
	"$tmpdir/reqd_deps_PAeNA_pre.tmp" > "$tmpdir/reqd_deps_PAeNA.tmp"
else
    ln -s "$tmpdir/reqd_deps_PAeNA_pre.tmp" "$tmpdir/reqd_deps_PAeNA.tmp"
fi

PAeNA2NA  "$tmpdir/reqd_deps_PAeNA.tmp" > "$reqd_deps_NA_fn"

pkg_subgraph_deps -f "$tmpdir/updated_PAeNA.tmp" \
    "$tmpdir/reqd_deps_PAeNA.tmp" |
PAeNA2PAe > "$rebuild_PAe_fn"

printf '' > "$summary_cmp_fn"

# rebuilt previously
PAeNA2PAe "$tmpdir/packages_PAeNA.tmp" | sort -u > "$tmpdir/packages_PAe.tmp"

changed_pkgs_fn=$tmpdir/changed.tmp
awk 'NF == 3 {print $2 "\n" $3; next}
     NF == 1 {print}' "$rebuild_PAe_fn" |
sort -u > "$changed_pkgs_fn"

sort "$changed_pkgs_fn" "$changed_pkgs_fn" "$tmpdir/packages_PAe.tmp" |
uniq -c |
awk '$1 == 1 {print $2}' > "$packages_built_prev_fn.tmp"

verbose_print "done\n"

######################################################################
### comparison binaries against pkgsrc tree
verbose_print "  pkg_src_summary vs. pkg_summary comparison..."

eval /usr/pkg/libexec/distbb/wrapper \
    $PKG_CMP_SUMMARY_CMD "$pkg_src_summary_fn" "$PKG_ALL_SUMMARY" \
    > "$summary_cmp_fn" || true

grep '^<' $summary_cmp_fn > "$tmp_stderr_fn" || true
if test -s "$tmp_stderr_fn"; then
    cat >> "$errors_fn" <<'EOF'
------------------
Versions of some packages go backward
EOF
    indent2 "$tmp_stderr_fn" >> "$errors_fn"
fi

verbose_print "done\n"

######################################################################
### list of already built packages

verbose_print "  copying auxiliary files..."

cp "$reqd_deps_NA_fn" "$aux_reqd_deps_fn"

verbose_print "done\n"

######################################################################
