#! /bin/bash
BASEDIR="$(dirname "$0")"
TEMPFILE=downward.tmp.$$
cat > $TEMPFILE

if [[ "$(uname -o)" == "Cygwin" ]]; then
    # Not sure how to handle time in Cygwin (command time doesn't work).
    # Ignoring it for now.
    STATE_SIZE=$("$BASEDIR/dispatch" $TEMPFILE)
    UNIT_COST=$("$BASEDIR/unitcost" $TEMPFILE)
else
    if [[ "$(uname)" == "Darwin" ]]; then
        # Need to explicitly ask for GNU time (from MacPorts) on Mac OS X.
        TIME="gtime"
        if ! which $TIME >/dev/null; then
            echo "$TIME must be installed on Mac OSX (from MacPorts, perhaps) for this to work"
            exit 1
        fi
    else
        TIME="command time"
    fi
    TIME="$TIME --output=elapsed.time --format=%S\n%U\n"
    STATE_SIZE=$($TIME --append "$BASEDIR/dispatch" $TEMPFILE)
    UNIT_COST=$($TIME --append "$BASEDIR/unitcost" $TEMPFILE)
fi

echo Dispatcher selected state size $STATE_SIZE.
echo This is a $UNIT_COST task.
PLANNER="$BASEDIR/downward-$STATE_SIZE"

function run_portfolio {
    PORTFOLIO="$1"
    shift
    # Set soft memory limit of 50 MB to avoid Python using too much space.
    # On the maia cluster, 20 MB have been tested to be sufficient; 18 MB are not.
    ulimit -Sv 51200
    "$PORTFOLIO" "$TEMPFILE" "$UNIT_COST" "$PLANNER" "$@"
    # Explicit is better than implicit: return portfolio's exit code.
    return $?
}

if [[ "$1" == "ipc" ]]; then
    CONFIG="$2"
    shift 2
    PORTFOLIO_SCRIPT="$BASEDIR/downward-$CONFIG.py"
    if [[ -e "$PORTFOLIO_SCRIPT" ]]; then
        # Handle configs seq-{sat,opt}-fdss-{1,2} and seq-opt-merge-and-shrink.
        run_portfolio "$PORTFOLIO_SCRIPT" "$@"
    elif [[ "$CONFIG" == "seq-sat-fd-autotune-1" ]]; then
        "$PLANNER" \
            --heuristic "hFF=ff(cost_type=1)" \
            --heuristic "hCea=cea(cost_type=0)" \
            --heuristic "hCg=cg(cost_type=2)" \
            --heuristic "hGoalCount=goalcount(cost_type=0)" \
            --heuristic "hAdd=add(cost_type=0)" \
            --search "iterated([
                lazy(alt([single(sum([g(),weight(hFF, 10)])),
                          single(sum([g(),weight(hFF, 10)]),pref_only=true)],
                          boost=2000),
                     preferred=hFF,reopen_closed=false,cost_type=1),
                lazy(alt([single(sum([g(),weight(hAdd, 7)])),
                          single(sum([g(),weight(hAdd, 7)]),pref_only=true),
                          single(sum([g(),weight(hCg, 7)])),
                          single(sum([g(),weight(hCg, 7)]),pref_only=true),
                          single(sum([g(),weight(hCea, 7)])),
                          single(sum([g(),weight(hCea, 7)]),pref_only=true),
                          single(sum([g(),weight(hGoalCount, 7)])),
                          single(sum([g(),weight(hGoalCount, 7)]),pref_only=true)],
                          boost=1000),
                     preferred=[hCea,hGoalCount],
                     reopen_closed=false,cost_type=1),
                lazy(alt([tiebreaking([sum([g(),weight(hAdd, 3)]),hAdd]),
                          tiebreaking([sum([g(),weight(hAdd, 3)]),hAdd],pref_only=true),
                          tiebreaking([sum([g(),weight(hCg, 3)]),hCg]),
                          tiebreaking([sum([g(),weight(hCg, 3)]),hCg],pref_only=true),
                          tiebreaking([sum([g(),weight(hCea, 3)]),hCea]),
                          tiebreaking([sum([g(),weight(hCea, 3)]),hCea],pref_only=true),
                          tiebreaking([sum([g(),weight(hGoalCount, 3)]),hGoalCount]),
                          tiebreaking([sum([g(),weight(hGoalCount, 3)]),hGoalCount],pref_only=true)],
                         boost=5000),
                     preferred=[hCea,hGoalCount],reopen_closed=false,cost_type=0),
                eager(alt([tiebreaking([sum([g(),weight(hAdd, 10)]),hAdd]),
                           tiebreaking([sum([g(),weight(hAdd, 10)]),hAdd],pref_only=true),
                           tiebreaking([sum([g(),weight(hCg, 10)]),hCg]),
                           tiebreaking([sum([g(),weight(hCg, 10)]),hCg],pref_only=true),
                           tiebreaking([sum([g(),weight(hCea, 10)]),hCea]),
                           tiebreaking([sum([g(),weight(hCea, 10)]),hCea],pref_only=true),
                           tiebreaking([sum([g(),weight(hGoalCount, 10)]),hGoalCount]),
                           tiebreaking([sum([g(),weight(hGoalCount, 10)]),hGoalCount],pref_only=true)],
                          boost=500),
                      preferred=[hCea,hGoalCount],reopen_closed=true,
                      pathmax=true,cost_type=0)],
                repeat_last=true,continue_on_fail=true)" "$@" < $TEMPFILE
    elif [[ "$CONFIG" == "seq-sat-fd-autotune-2" ]]; then
        "$PLANNER" \
            --heuristic "hCea=cea(cost_type=2)" \
            --heuristic "hCg=cg(cost_type=1)" \
            --heuristic "hGoalCount=goalcount(cost_type=2)" \
            --heuristic "hFF=ff(cost_type=0)" \
            --search "iterated([
                ehc(hCea, preferred=hCea,preferred_usage=0,cost_type=0),
                lazy(alt([single(sum([weight(g(), 2),weight(hFF, 3)])),
                          single(sum([weight(g(), 2),weight(hFF, 3)]),pref_only=true),
                          single(sum([weight(g(), 2),weight(hCg, 3)])),
                          single(sum([weight(g(), 2),weight(hCg, 3)]),pref_only=true),
                          single(sum([weight(g(), 2),weight(hCea, 3)])),
                          single(sum([weight(g(), 2),weight(hCea, 3)]),pref_only=true),
                          single(sum([weight(g(), 2),weight(hGoalCount, 3)])),
                          single(sum([weight(g(), 2),weight(hGoalCount, 3)]),pref_only=true)],
                         boost=200),
                     preferred=[hCea,hGoalCount],reopen_closed=false,cost_type=1),
                lazy(alt([single(sum([g(),weight(hFF, 5)])),
                          single(sum([g(),weight(hFF, 5)]),pref_only=true),
                          single(sum([g(),weight(hCg, 5)])),
                          single(sum([g(),weight(hCg, 5)]),pref_only=true),
                          single(sum([g(),weight(hCea, 5)])),
                          single(sum([g(),weight(hCea, 5)]),pref_only=true),
                          single(sum([g(),weight(hGoalCount, 5)])),
                          single(sum([g(),weight(hGoalCount, 5)]),pref_only=true)],
                         boost=5000),
                     preferred=[hCea,hGoalCount],reopen_closed=true,cost_type=0),
                lazy(alt([single(sum([g(),weight(hFF, 2)])),
                          single(sum([g(),weight(hFF, 2)]),pref_only=true),
                          single(sum([g(),weight(hCg, 2)])),
                          single(sum([g(),weight(hCg, 2)]),pref_only=true),
                          single(sum([g(),weight(hCea, 2)])),
                          single(sum([g(),weight(hCea, 2)]),pref_only=true),
                          single(sum([g(),weight(hGoalCount, 2)])),
                          single(sum([g(),weight(hGoalCount, 2)]),pref_only=true)],
                         boost=1000),
                     preferred=[hCea,hGoalCount],reopen_closed=true,cost_type=1)],
                repeat_last=true,continue_on_fail=true)" "$@" < $TEMPFILE
    elif [[ "$CONFIG" == "seq-sat-lama-2008" ]]; then
        echo "The seq-sat-lama-2008 planner should not use this code."
        exit 2
    elif [[ "$CONFIG" == "seq-sat-lama-2011" ]]; then
        if [[ "$UNIT_COST" == "unit" ]]; then
            "$PLANNER" \
                --heuristic "hlm,hff=lm_ff_syn(lm_rhw(
                    reasonable_orders=true,lm_cost_type=2,cost_type=2))" \
                --search "iterated([
                    lazy_greedy([hff,hlm],preferred=[hff,hlm]),
                    lazy_wastar([hff,hlm],preferred=[hff,hlm],w=5),
                    lazy_wastar([hff,hlm],preferred=[hff,hlm],w=3),
                    lazy_wastar([hff,hlm],preferred=[hff,hlm],w=2),
                    lazy_wastar([hff,hlm],preferred=[hff,hlm],w=1)],
                    repeat_last=true,continue_on_fail=true)" \
                "$@" < $TEMPFILE
        elif [[ "$UNIT_COST" == "nonunit" ]]; then
            "$PLANNER" \
                --heuristic "hlm1,hff1=lm_ff_syn(lm_rhw(
                    reasonable_orders=true,lm_cost_type=1,cost_type=1))" \
                --heuristic "hlm2,hff2=lm_ff_syn(lm_rhw(
                    reasonable_orders=true,lm_cost_type=2,cost_type=2))" \
                --search "iterated([
                    lazy_greedy([hff1,hlm1],preferred=[hff1,hlm1],
                                cost_type=1,reopen_closed=false),
                    lazy_greedy([hff2,hlm2],preferred=[hff2,hlm2],
                                reopen_closed=false),
                    lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=5),
                    lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=3),
                    lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=2),
                    lazy_wastar([hff2,hlm2],preferred=[hff2,hlm2],w=1)],
                    repeat_last=true,continue_on_fail=true)" \
                "$@" < $TEMPFILE
        else
            echo "Something is seriously messed up!"
            exit 2
        fi
    elif [[ "$CONFIG" == "seq-opt-fd-autotune" ]]; then
        "$PLANNER" \
            --heuristic "hLMCut=lmcut()" \
            --heuristic "hHMax=hmax()" \
            --heuristic "hCombinedSelMax=selmax(
                [hLMCut,hHMax],alpha=4,classifier=0,conf_threshold=0.85,
                training_set=10,sample=0,uniform=true)" \
            --search "astar(hCombinedSelMax,mpd=false,
                            pathmax=true,cost_type=0)" "$@" < $TEMPFILE
    elif [[ "$CONFIG" == "seq-opt-selmax" ]]; then
        "$PLANNER" --search "astar(selmax([lmcut(),lmcount(lm_merged([lm_hm(m=1),lm_rhw()]),admissible=true)],training_set=1000),mpd=true)" "$@" < $TEMPFILE
    elif [[ "$CONFIG" == "seq-opt-bjolp" ]]; then
        "$PLANNER" --search "astar(lmcount(lm_merged([lm_rhw(),lm_hm(m=1)]),admissible=true),mpd=true)" "$@" < $TEMPFILE
    elif [[ "$CONFIG" == "seq-opt-lmcut" ]]; then
        "$PLANNER" --search "astar(lmcut())" "$@" < $TEMPFILE
    else
        echo "unknown IPC planner name: $CONFIG"
        exit 2
    fi
elif [[ "$1" == "--portfolio" ]]; then
    # Portfolio files must reside in the search directory.
    PORTFOLIO="$2"
    shift 2
    run_portfolio "$BASEDIR/$PORTFOLIO" "$@"
else
    "$PLANNER" "$@" < $TEMPFILE
fi
EXITCODE=$?
rm -f $TEMPFILE
exit $EXITCODE
