#!/bin/bash 
BS_SERVER="home.rasher.dk"
BS_PORT=33010

GCC_334_DIR="`dirname $0`/gcc-3.3.4/bin" # Path to the bin dir containing gcc-3.3.4 for sh1 (may be relative)
GCC_304_DIR="`dirname $0`/gcc-3.0.4/bin" # Ditto for 3.0.4

exitmsg() {
    echo $1
    exit
}

ramusage() {
    cat > ramusage.pl <<'MOO'
#!/usr/bin/perl
sub mapscan {
    my ($f)=@_;
    my $start,$loadstart=-1, $end;
    open(M, "<$f");
    while(<M>) {
        if($_ =~ / +0x([0-9a-f]+) *_end\s*=\s*\./) {
            $end = $1;
            last;
        }
        elsif($_ =~ / +0x([0-9a-f]+) *_loadaddress\s*=\s*\./) {
            $loadstart = $1;
        }
        elsif($_ =~ / +0x([0-9a-f]+) *start$/) {
            $start = $1;
        }
    }
    close(M);
    if($loadstart>=0) {
        $start=$loadstart;
    }

    # return number of bytes
    return hex($end) - hex($start);
}

printf("%d\n", mapscan($ARGV[0]));
MOO
chmod u+x ramusage.pl
}

cd `dirname $0`
READY="READY `uname -m` current"
if [ -d "$GCC_334_DIR" ]; then
    GCC_334_DIR=`cd "$GCC_334_DIR"; pwd`
    READY="$READY 334"
else
    GCC_334_DIR=""
fi
if [ -d "$GCC_304_DIR" ]; then
    GCC_304_DIR=`cd "$GCC_304_DIR"; pwd`
    READY="$READY 304"
else
    GCC_304_DIR=""
fi

# Do the git dance
# http://www.rockbox.org/twiki/bin/view/Main/GitVersionControl#The_public_Rockbox_git_repositor
if [ -d "rockbox/.git" ]; then
    rm -rf rockbox
fi
if [ ! -d "rockbox" ]; then
    if [ -f "rockbox.tar.gz" ]; then
        tar xzf rockbox.tar.gz
    else
        git clone git://git.rockbox.org/rockbox
        pushd rockbox > /dev/null 2>&1
        git update-ref refs/remotes/git-svn origin/master
        git svn init svn://svn.rockbox.org/rockbox/trunk
        git svn fetch
        git repack
        popd > /dev/null 2>&1
        tar cvzf rockbox.tar.gz rockbox
    fi
else
    echo "You seem to have a non-git rockbox dir. I can't work with that."
fi
if [ ! -d "rockbox" ]; then
    exitmsg "WEEEEEEEEEEP! Can't checkout or something :<"
fi
pushd rockbox > /dev/null 2>&1


while true; do
    # Ask the server for a job
    printf "$READY"|nc $BS_SERVER $BS_PORT 2>/dev/null |sed 's/\\/\\\\/g'|(
        read target revision confstring
        if [ "x$target" = "xDONE" ]; then
            echo "No more builds waiting"
            exit 1
        elif [ "x$target" = "x" ]; then
            echo "Connection failed or no response"
            exit 2
        elif [ "x$target" = "xI" ]; then
            echo "Connection refused"
            exit 3
        fi
        printf "[%s] Building r%d for %s (%s)... " "`date +%T`" "$revision" "$target" "$confstring"
        git svn rebase > /dev/null 2>&1
        gitoutput=$(git checkout $(git svn find-rev r$revision) 2>&1)

        # Check that we do in fact have the right revision
        realversion=`git log --grep='git-svn-id: svn' -1 | tail -n 1 | perl -ne 'm/@(\d*)/; print "r" . $1;'`
        if [ "$realversion" != "r$revision" ]; then
            exitmsg "Checkout failed - $realversion != r$revision ($gitoutput)"
        fi

        rm -rf build-$revision > /dev/null 2>&1
        mkdir build-$revision
        pushd build-$revision > /dev/null 2>&1
        # Some stuff was renamed
        touch ../apps/plugins/tetrox.c
        touch ../apps/plugins/bejeweled.c
        if [ -f ../apps/plugins/bitmaps/native/jewels.112x64x1.bmp ]; then
            for i in ../apps/plugins/bitmaps/native/jewels.*; do
                new=`echo $i |sed 's/jewels/bejeweled_jewels/'`
                ln -s "`basename $i`" "$new"
            done
        fi

        newpath=$PATH
        if echo $target|grep -q -E "(recorder|recorderv2|player|fmrecorder|recorder8mb|ondiosp|ondiofm)"; then
            if [ $revision -lt 4933 -a "x$GCC_304_DIR" != "x" ]; then
                printf "(using GCC 3.0.4) "
                newpath="$GCC_304_DIR:$PATH"
            elif [ $revision -lt 9857 -a "x$GCC_334_DIR" != "x" ]; then
                printf "(using GCC 3.3.4) "
                newpath="$GCC_334_DIR:$PATH"
            fi
        fi

        if [ "`uname -m`" = "x86_64" -a $revision -gt 8417 -a $revision -lt 8626 ]; then
            printf "REJECTED\n"
            ram=-2
            bin=-2
        else
            make -C ../tools > /dev/null 2>&1

            # For new builds, we can make bin, which is faster
            # This was broken between 16323 and 16351
            if [ $revision -gt 10612 -a \( $revision -lt 16323 -o $revision -gt 16351 \) ]; then
                bin="bin"
                printf "(make bin) "
            else
                bin=""
            fi

            # Always build single-threaded.
            printf "$confstring" |PATH=${newpath} ../tools/configure > /dev/null 2>&1
            MAKEFLAGS="" PATH=$newpath V=1 make $bin -j 1 > ../../$target-$revision.log 2>&1
            # If we have both a rockbox/archos.bin and .map, chances are, we have a succesful build
            if [ -f "$(find -name rockbox.map -o -name archos.map)" -a -f "$(find -name rockbox.bin -o -name archos.bin)" ]; then
                ramusage
                ram=$(./ramusage.pl $(find -name rockbox.map -o -name archos.map))
                bin=$(stat -c %s $(find -name rockbox.bin -o -name archos.bin))
                printf "done (bin: %d, ram: %d)\n" "$bin" "$ram"
                rm ../../$target-$revision.log
            else
                printf "FAILED\n"
                ram=0
                bin=0
            fi
        fi
        popd > /dev/null
        rm -rf build-* apps/plugins/tetrox.c apps/plugins/bejeweled.c apps/plugins/bitmaps/native/bejeweled*
        git clean -f -d > /dev/null 2>&1
        resp=`printf "target:%s revision:%d bin:%d ram:%d" "$target" "$revision" "$bin" "$ram" |nc $BS_SERVER $BS_PORT`
    ) || exit
    sleep 1
done
popd > /dev/null 2>&1
