#vim: ft=sh

SOFTWARE_DIR="$RBBT_SOFTWARE_DIR"
OPT_DIR="$SOFTWARE_DIR/opt"; [ -d $OPT_SRC_DIR ] || mkdir -p $OPT_SRC_DIR
OPT_BIN_DIR="$OPT_DIR/bin"; [ -d $OPT_BIN_DIR ] || mkdir -p $OPT_BIN_DIR
OPT_SRC_DIR="$SOFTWARE_DIR/src"; [ -d $OPT_SRC_DIR ] || mkdir -p $OPT_SRC_DIR
OPT_SCM_DIR="$SOFTWARE_DIR/scm"; [ -d $OPT_SCM_DIR ] || mkdir -p $OPT_SCM_DIR
OPT_JAR_DIR="$OPT_DIR/jars"; [ -d $OPT_JAR_DIR ] || mkdir -p $OPT_JAR_DIR
OPT_BUILD_DIR="$SOFTWARE_DIR/.build"; [ -d $OPT_BUILD_DIR ] || mkdir -p $OPT_BUILD_DIR

mkdir -p "$OPT_BUILD_DIR"

function link(){
  local source="$1"
  local target="$2"
  local rel_source=$(realpath --relative-to="$(dirname $target)" "$source")
  
  [ -h "$target" ] && rm "$target"
  echo ln -s "$rel_source" "$target" 1>&2
  [ -h "$target" ] || ln -s "$rel_source" "$target"
}

function expand_path(){
  name=$(basename $1)
  dir=$(dirname $1)

  echo "$(cd $dir && pwd)/$name"
}

function add2file(){
    file=$1
    line=$2

    rel="$(realpath -s --relative-to="$OPT_DIR" "$line")"
    grep "$rel" "$file" || echo "$rel" >> "$file"
}

#{{{ GET PKG OPT_BUILD_DIR

# From SRC
get_pkg(){
    local name="$1"
    local url="$2"

    if [ ! -f "$OPT_SRC_DIR/$name.pkg" ]; then
        wget "$url" -O "$OPT_SRC_DIR/$name.pkg"  || wget "$url" -O "$OPT_SRC_DIR/$name.pkg" --no-check-certificate
    fi
}

uncompress_pkg(){
    local name="$1"
    local pkg="$OPT_SRC_DIR/$name.pkg"

    local old_pwd="`expand_path $(pwd)`"
    clean_build

    mkdir -p "$OPT_BUILD_DIR"
    cd "$OPT_BUILD_DIR"

    (tar xvfz $pkg || tar xvfJ $pkg || tar xvfj $pkg || unzip $pkg || echo "Error decompressing") 2> /dev/null

    cd "$old_pwd"
}

get_src(){
    local name="$1"
    local url="$2"

    get_pkg "$name" "$url"
    uncompress_pkg "$name"
}

# From SNV
get_svn(){
    local name="$1"
    local url="$2"

    local old_pwd="`expand_path $(pwd)`"

    cd $OPT_SCM_DIR
    if [ -d "$name" ]; then
        cd "$name" 
        svn update
    else
        echo svn checkout "$url" "$name"
        svn checkout "$url" "$name"
    fi

    clean_build

    cd $OPT_BUILD_DIR
    link "$OPT_SCM_DIR/$name" "$name"

    cd "$old_pwd"

}

# From GIT
get_git(){
    local name="$1"
    local url="$2"

    local old_pwd="`expand_path $(pwd)`"

    cd $OPT_SCM_DIR
    if [ -d "$name" ]; then
        cd "$name" 

        if [ ! "$NOWEB" == "true" ]; then
          git stash
          git pull origin master
          git rebase master
          git stash apply
        fi
    else
        git clone "$url" "$name"
    fi

    clean_build

    cd $OPT_BUILD_DIR
    link "$OPT_SCM_DIR/$name" "$name"

    cd "$old_pwd"
}


#{{{ BUILD PKG in OPT_BUILD_DIR

clean_build(){
    rm -Rf $OPT_BUILD_DIR/*
}

build_dir(){
    echo $OPT_BUILD_DIR/`ls $OPT_BUILD_DIR |head -n 1`
}

compile(){
    local name=$1; shift
    local extra="$@"

    if [ -f Makefile -o -f makefile ]; then
        make || exit -1
        make install || echo "No install"
    fi

    [ -f build.xml ] && (ant || exit -1)

    [ -f setup.rb ] && (ruby -Ilib/ setup.rb --prefix="$(opt_dir "$name")" $extra || exit -1)

    [ -f install.rb ] && ruby -Ilib/ install.rb config --prefix="$(opt_dir "$name")" $extra && ruby -Ilib/ install.rb install

    if [ -f setup.py ]; then 
        python setup.py build &&  python setup.py install --user || exit -1
        clean_build 
    fi
}

build(){
    local name=$1; shift
    local extra="$@"

    echo "Building $name"
    if [ "x$extra" != "x" ]; then
        echo "Extra params: $extra"
    fi

    local old_pwd="`expand_path $(pwd)`"
    cd "`build_dir`"
    echo PWD: `pwd`
    ls

    if [ -f config/m4 ]; then
        libtoolize --force
        aclocal
        autoheader
    fi

    if [ -f Makefile.am -a ! -f configure ]; then
      autoreconf
    fi

    if [ -f aclocal.m4 ]; then
        autoconf
    fi

    if [ -f autogen.sh ]; then
        ./autogen.sh
    fi

    if [ -f aclocal.m4 ]; then
        autoreconf -i
        autoconf
        automake
    else
        autoconf
        automake
    fi

    if [ -f config ]; then
        ln -s config configure
    fi

    if [ -f CMakeLists.txt ]; then
        mkdir build
        cd build
        cmake -DCMAKE_INSTALL_PREFIX:PATH=/ ..
        make -j4
        make DESTDIR="$(opt_dir "$name")" install
        setup "$name"
        clean_build
    fi
    
    if [ -f configure ]; then 
        echo ./configure --prefix="$(opt_dir "$name")" $extra
        ./configure --prefix="$(opt_dir "$name")" $extra
        compile "$name" $extra
        setup "$name"
        clean_build
    else
        compile "$name" $extra
        move_opt "$name"
        setup "$name"
        clean_build
    fi

    
    cd "$old_pwd"
}

#{{{ SETUP

versioned?(){
    local name="$1"
    [[ $name =~ : ]]
}

opt_dir(){
    local name="$1"
    if versioned? "$name"; then
        local real_name=`echo $1 | sed 's/:.*//'`
        local version=`echo $1 | sed 's/.*://'`
        echo "$OPT_DIR/$real_name/$version"
    else
        echo "$OPT_DIR/$name"
    fi
}

move_opt(){
    local name="$1"
    local pkg_dir=$(opt_dir "$name")
    local source=$(build_dir)

    mkdir -p $(dirname "$pkg_dir")
    if [ -h "$source" ]; then
      local real_source=$(realpath "$source")
      echo link "$real_source" "$pkg_dir"
      link "$real_source" "$pkg_dir"
    else
      mv "$source" "$pkg_dir"
    fi
}

setup(){
    local name="$1"
    local pkg_dir="`opt_dir \"$name\"`"

    if versioned? "$name"; then
        rm -f "$(dirname $pkg_dir)/current"
        link "$pkg_dir" "$(dirname $pkg_dir)/current"
        pkg_dir="$(dirname $pkg_dir)/current"
    fi

    if [ -d "$pkg_dir/bin/" ]; then

        for exe in ` find "$pkg_dir/bin/" -maxdepth 1 -type f -executable`; do
            exe=$(basename $exe)
            rm -f "$OPT_DIR/bin/$exe"
            link "$pkg_dir/bin/$exe" "$OPT_DIR/bin/$exe" 2>/dev/null
        done

    else
        local old_pwd="`expand_path $(pwd)`"

        for exe in ` find "$pkg_dir/" -maxdepth 1 -type f -executable`; do
            exe=$(basename $exe)
            rm -f "$OPT_DIR/bin/$exe"
            link "$pkg_dir/$exe" "$OPT_DIR/bin/$exe" 2>/dev/null
        done
    fi
    
    ([ -d "$pkg_dir/include" ]       && add2file "$OPT_DIR/.c-paths" "$pkg_dir/include")
    ([ -d "$pkg_dir/lib" ]           && add2file "$OPT_DIR/.ld-paths" "$pkg_dir/lib")
    ([ -d "$pkg_dir/lib/pkgconfig" ] && add2file "$OPT_DIR/.pkgconfig-paths" "$pkg_dir/lib/pkgconfig")
}

#{{{ HELPERS

install_src(){
    local name="$1"
    local url="$2"
    shift;shift;
    local extra="$@"
    
    get_pkg "$name" "$url"
    uncompress_pkg "$name"
    build "$name"  "$extra"
}

install_svn(){
    local name="$1"
    local url="$2"
    shift;shift;
    local extra="$@"
    
    get_svn "$name" "$url"
    build "$name" $extra
}

custom_build(){
    local name="$1"
    shift;
    local cmd="$@"

    echo "Building $name"

    local old_pwd="`expand_path $(pwd)`"
    cd "`build_dir`"
    echo `pwd`
    ls

    eval $cmd

    move_opt "$name"
    setup "$name"
    clean_build
    
    cd "$old_pwd"
}

install_git(){
    local name="$1"
    local url="$2"
    shift;shift;
    local extra="$@"
    
    get_git "$name" "$url"
    build "$name" $extra
}

install_jar(){
    local name="$1"
    local url="$2"

    [ -d  "$OPT_DIR/$name/" ] || mkdir -p  "$OPT_DIR/$name/"
    wget "$url" -O "$OPT_DIR/jars/$name.jar" | wget "$url" -O "$OPT_DIR/jars/$name.jar" --no-check-certificate
    link "$OPT_DIR/$name/$name.jar" "$OPT_JAR_DIR/$name.jar" 
}

jar2bin(){
    local name="$1";shift
    local extra="$@"

    echo "#!/bin/bash" > $OPT_DIR/bin/$name
    echo "java $extra -jar '$OPT_JAR_DIR/$name.jar'" >> $OPT_DIR/bin/$name

    chmod +x $OPT_DIR/bin/$name
}

# vim: ft=sh