#!/bin/sh

set -e -x

# TODO.  Several variables are not properly quoted/escaped where they are
# passed to another shell.

project=$1
[ $# = 0 ] || shift
build_suffix=.build
case $project in
  binutils-gdb)
    branch=tschwinge/W._C._Handy
    linux_host=kepler.SCHWINGE
    hurd_host=laplace.SCHWINGE
    ;;
  boehm-gc)
    branch=master
    linux_host=kepler.SCHWINGE
    hurd_host=laplace.SCHWINGE
    ;;
  gcc)
    branch=hurd/master
    linux_host=kepler.SCHWINGE
    hurd_host=laplace.SCHWINGE
    ;;
  glibc)
    branch=tschwinge/Roger_Whittaker
    #linux_host=kepler.SCHWINGE
    hurd_host=laplace.SCHWINGE
    ;;
  llvm)
    branch=tschwinge/Horace_Silver
    linux_host=kepler.SCHWINGE
    hurd_host=laplace.SCHWINGE
    ;;
  *)
    echo >&2 "Don't know about project »$project«."
    exit 1
    ;;
esac

step=$1
[ $# = 0 ] || shift
case $step in
  build | install | test)
    ;;
  '')
    # If there is no step specified, try a default set.
    "$0" "$project" build "$@"
    "$0" "$project" install "$@"
    "$0" "$project" test "$@"
    exit
    ;;
  *)
    echo >&2 "Don't know about step »$step«."
    exit 1
    ;;
esac

action=$1
[ $# = 0 ] || shift
case $action in
  fetch | diff)
    ;;
  '')
    # If there is no action specified, try a default set.
    "$0" "$project" "$step" fetch "$@"
    "$0" "$project" "$step" diff "$@"
    exit
    ;;
  *)
    echo >&2 "Don't know about action »$action«."
    exit 1
    ;;
esac

case $project:$action in
  binutils-gdb:fetch | boehm-gc:fetch | gcc:fetch | glibc:fetch | llvm:fetch)
    host=$1
    [ $# = 0 ] || shift
    case $host in
      kepler.SCHWINGE)
        project_base=tmp/source/"$project"
        mount=/media/data
        ;;
      laplace.SCHWINGE)
        project_base=tmp/"$project"
        mount=/media/erich
        ;;
      '')
        # If there is no host specified, try a default set.
        : "${linux_host:?}"
        : "${hurd_host:?}"
        "$0" "$project" "$step" "$action" "$linux_host" "$@"
        "$0" "$project" "$step" "$action" "$hurd_host" "$@"
        exit
        ;;
      *)
        echo >&2 "Don't know about host »$host«."
        exit 1
        ;;
    esac

    [ $# = 0 ]

    : "${branch:?}"
    : "${build_suffix:?}"
    : "${host:?}"
    : "${mount:?}"
    : "${project_base:?}"
    # Log files.
    case $project:$step in
      binutils-gdb:build | binutils-gdb:install | binutils-gdb:test \
      | boehm-gc:build | boehm-gc:install | boehm-gc:test \
      | gcc:build | gcc:install | gcc:test \
      | glibc:build | glibc:install | glibc:test \
      | llvm:build | llvm:install | llvm:test)
        ssh \
          "$host" \
          'cd '"$project_base"'/ && \
          cat '"$branch$build_suffix"'/log_'"$step"'* \
            | sed -e "s%\('"$mount"'\)\?${PWD}%[...]%g"' \
          > toolchain/logs/"$project"/"$host"/log_"$step"
        if test -f toolchain/logs/"$project"/"$host"/log_"$step".sed; then
          sed \
            -f toolchain/logs/"$project"/"$host"/log_"$step".sed \
            -i toolchain/logs/"$project"/"$host"/log_"$step"
        fi
        ;;
      *)
        echo >&2 "Internal error."
        exit 1
        ;;
    esac
    # Detailed log files.
    case $project:$step in
      binutils-gdb:build | binutils-gdb:install \
      | boehm-gc:build | boehm-gc:install | boehm-gc:test \
      | gcc:build | gcc:install \
      | glibc:build | glibc:install | glibc:test \
      | llvm:build | llvm:install | llvm:test)
        :
        ;;
      binutils-gdb:test \
      | gcc:test)
        # First, create a temporary directory, where the *.sum files are copied
        # into, and then individually filtered through sed.
        ssh \
          "$host" \
            'cd '"$project_base"'/ && \
            mkdir -p '"$branch$build_suffix"'.sums && \
            rsync \
              -vr --prune-empty-dirs --delete \
              --include=\*.sum --filter=hide,!\ \*/ \
              '"$branch$build_suffix"'/ \
              '"$branch$build_suffix"'.sums/ && \
            find '"$branch$build_suffix"'.sums/ -type f \
              -exec sed -e "s%\('"$mount"'\)\?${PWD}%[...]%g" -i \{\} \;'
        case $project in
          gcc)
            # Rename host-specific directory to a generic name.
            # This is probably not the most beautiful solution.
            case $host in
              "$linux_host")
                arch=i686-pc-linux-gnu
                ;;
              "$hurd_host")
                arch=i686-unknown-gnu0.5
                ;;
              *)
                echo >&2 "Internal error."
                exit 1
                ;;
            esac
            ssh \
              "$host" \
                'cd '"$project_base"'/'"$branch$build_suffix"'.sums/ && \
                if test -d '"$arch"'; then mv '"$arch"' [ARCH]; fi'
            ;;
        esac
        rsync \
          -vr --delete \
          "$host":"$project_base"/"$branch$build_suffix".sums/ \
          toolchain/logs/"$project"/"$host"/"$step"/
        ;;
      *)
        echo >&2 "Internal error."
        exit 1
        ;;
    esac
    exit
    ;;
  binutils-gdb:diff | boehm-gc:diff | gcc:diff | llvm:diff)
    [ $# = 0 ]

    : "${linux_host:?}"
    : "${hurd_host:?}"
    case $project:$step in
      binutils-gdb:build | binutils-gdb:install | binutils-gdb:test \
      | boehm-gc:build | boehm-gc:install | boehm-gc:test \
      | gcc:build | gcc:install | gcc:test \
      | llvm:build | llvm:install | llvm:test)
        sed \
          -f toolchain/logs/"$project"/"$linux_host"/log_"$step".diff.sed \
          < toolchain/logs/"$project"/"$linux_host"/log_"$step" \
          > toolchain/logs/"$project"/"$linux_host"/log_"$step"_
        sed \
          -f toolchain/logs/"$project"/"$hurd_host"/log_"$step".diff.sed \
          < toolchain/logs/"$project"/"$hurd_host"/log_"$step" \
          > toolchain/logs/"$project"/"$hurd_host"/log_"$step"_
        r=0
        git diff --no-index \
          --ignore-space-change --patience \
          toolchain/logs/"$project"/"$linux_host"/log_"$step"_ \
          toolchain/logs/"$project"/"$hurd_host"/log_"$step"_ \
          > toolchain/logs/"$project"/log_"$step".diff \
        || r=$?
        rm \
          -f \
          toolchain/logs/"$project"/"$linux_host"/log_"$step"_ \
          toolchain/logs/"$project"/"$hurd_host"/log_"$step"_
        [ "$r" = 0 ] || [ "$r" = 1 ]
        ;;
      *)
        echo >&2 "Internal error."
        exit 1
        ;;
    esac
    case $project:$step in
      binutils-gdb:build | binutils-gdb:install \
      | boehm-gc:build | boehm-gc:install | boehm-gc:test \
      | gcc:build | gcc:install \
      | llvm:build | llvm:install | llvm:test)
        :
        ;;
      binutils-gdb:test \
      | gcc:test)
        r=0
        git diff --no-index \
          --ignore-space-change --patience \
          toolchain/logs/"$project"/"$linux_host"/"$step"/ \
          toolchain/logs/"$project"/"$hurd_host"/"$step"/ \
          > toolchain/logs/"$project"/"$step".diff \
        || r=$?
        [ "$r" = 0 ] || [ "$r" = 1 ]
        ;;
      *)
        echo >&2 "Internal error."
        exit 1
        ;;
    esac
    exit
    ;;
  *)
    echo >&2 "Internal error."
    exit 1
    ;;
esac

echo >&2 "Internal error."
exit 1