#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e                # exit on error

cd `dirname "$0"`     # connect to root

VERSION=`cat share/VERSION.txt`

function usage {
  echo "Usage: $0 {test|dist|sign|clean|docker|rat}"
  exit 1
}

if [ $# -eq 0 ]
then
  usage
fi

set -x                # echo commands

for target in "$@"
do
  case "$target" in

    test)
      # run lang-specific tests
      (cd lang/java; mvn test)
      (cd lang/py; ant test)
      (cd lang/py3; python3 setup.py test)
      (cd lang/c; ./build.sh test)
      (cd lang/c++; ./build.sh test)
      (cd lang/csharp; ./build.sh test)
      (cd lang/js; ./build.sh test)
      (cd lang/ruby; ./build.sh test)
      (cd lang/php; ./build.sh test)
      (cd lang/perl; perl ./Makefile.PL && make test)

      # create interop test data
      mkdir -p build/interop/data
      (cd lang/java/avro; mvn -P interop-data-generate generate-resources)
      (cd lang/py; ant interop-data-generate)
      (cd lang/c; ./build.sh interop-data-generate)
      #(cd lang/c++; make interop-data-generate)
      (cd lang/ruby; rake generate_interop)
      (cd lang/php; ./build.sh interop-data-generate)

      # run interop data tests
      (cd lang/java; mvn test -P interop-data-test)
      (cd lang/py; ant interop-data-test)
      (cd lang/c; ./build.sh interop-data-test)
      #(cd lang/c++; make interop-data-test)
      (cd lang/ruby; rake interop)
      (cd lang/php; ./build.sh test-interop)

      # java needs to package the jars for the interop rpc tests
      (cd lang/java; mvn package -DskipTests)
      # run interop rpc test
      /bin/bash share/test/interop/bin/test_rpc_interop.sh
    ;;

    dist)
      # ensure version matches
      # FIXME: enforcer is broken:MENFORCER-42
      # mvn enforcer:enforce -Davro.version=$VERSION

      # build source tarball
      mkdir -p build

      SRC_DIR=avro-src-$VERSION
      DOC_DIR=avro-doc-$VERSION

      rm -rf build/${SRC_DIR}
      if [ -d .svn ];
      then
        svn export --force . build/${SRC_DIR}
      elif [ -d .git ];
      then
        mkdir -p build/${SRC_DIR}
        git archive HEAD | tar -x -C build/${SRC_DIR}
      else
        echo "Not SVN and not GIT .. cannot continue"
        exit -1;
      fi

      #runs RAT on artifacts
      mvn -N -P rat antrun:run

      mkdir -p dist
      (cd build; tar czf ../dist/${SRC_DIR}.tar.gz ${SRC_DIR})

      # build lang-specific artifacts

      (cd lang/java; mvn package -DskipTests -Dhadoop.version=1;
      rm -rf mapred/target/{classes,test-classes}/;
      rm -rf trevni/avro/target/{classes,test-classes}/;
      mvn -P dist package -DskipTests -Davro.version=$VERSION javadoc:aggregate)
      (cd lang/java/trevni/doc; mvn site)
      (mvn -N -P copy-artifacts antrun:run)

      (cd lang/py; ant dist)
      (cd lang/py3; python3 setup.py sdist; cp -r dist ../../dist/py3)

      (cd lang/c; ./build.sh dist)

      (cd lang/c++; ./build.sh dist)

      (cd lang/csharp; ./build.sh dist)

      (cd lang/js; ./build.sh dist)

      (cd lang/ruby; ./build.sh dist)

      (cd lang/php; ./build.sh dist)

      mkdir -p dist/perl
      (cd lang/perl; perl ./Makefile.PL && make dist)
      cp lang/perl/Avro-$VERSION.tar.gz dist/perl/

      # build docs
      (cd doc; ant)
      # add LICENSE and NOTICE for docs
      mkdir -p build/$DOC_DIR
      cp doc/LICENSE build/$DOC_DIR
      cp doc/NOTICE build/$DOC_DIR
      (cd build; tar czf ../dist/avro-doc-$VERSION.tar.gz $DOC_DIR)

      cp DIST_README.txt dist/README.txt
      ;;

    sign)
      set +x

      echo -n "Enter password: "
      stty -echo
      read password
      stty echo

      for f in $(find dist -type f \
        \! -name '*.md5' \! -name '*.sha1' \
        \! -name '*.asc' \! -name '*.txt' );
      do
        (cd `dirname $f`; md5sum `basename $f`) > $f.md5
        (cd `dirname $f`; sha1sum `basename $f`) > $f.sha1
        gpg --passphrase $password --armor --output $f.asc --detach-sig $f
      done

      set -x
      ;;

    clean)
      rm -rf build dist
      (cd doc; ant clean)

      (mvn clean)
      rm -rf lang/java/*/userlogs/
      rm -rf lang/java/*/dependency-reduced-pom.xml

      (cd lang/py; ant clean)
      rm -rf lang/py/userlogs/

      (cd lang/py3; python3 setup.py clean)
      rm -rf lang/py3/dist
      rm -rf lang/py3/avro_python3.egg-info
      rm -f  lang/py3/avro/*.avsc
      rm -f  lang/py3/avro/VERSION.txt
      rm -rf lang/py3/avro/__pycache__/
      rm -f  lang/py3/avro/tests/interop.avsc
      rm -rf lang/py3/avro/tests/__pycache__/

      (cd lang/c; ./build.sh clean)

      (cd lang/c++; ./build.sh clean)

      (cd lang/csharp; ./build.sh clean)

      (cd lang/js; ./build.sh clean)

      (cd lang/ruby; ./build.sh clean)

      (cd lang/php; ./build.sh clean)

      (cd lang/perl; [ ! -f Makefile ] || make clean)
      rm -f  lang/perl/Avro-*.tar.gz
      rm -f  lang/perl/META.yml
      rm -f  lang/perl/Makefile.old
      rm -rf lang/perl/inc/
      ;;

    docker)
      docker build -t avro-build share/docker
      if [ "$(uname -s)" == "Linux" ]; then
        USER_NAME=${SUDO_USER:=$USER}
        USER_ID=$(id -u $USER_NAME)
        GROUP_ID=$(id -g $USER_NAME)
      else # boot2docker uid and gid
        USER_NAME=$USER
        USER_ID=1000
        GROUP_ID=50
      fi
      docker build -t avro-build-${USER_NAME} - <<UserSpecificDocker
FROM avro-build
RUN groupadd -g ${GROUP_ID} ${USER_NAME} || true
RUN useradd -g ${GROUP_ID} -u ${USER_ID} -k /root -m ${USER_NAME}
ENV HOME /home/${USER_NAME}
UserSpecificDocker
      # By mapping the .m2 directory you can do an mvn install from
      # within the container and use the result on your normal
      # system.  And this also is a significant speedup in subsequent
      # builds because the dependencies are downloaded only once.
      docker run --rm=true -t -i \
        -v ${PWD}:/home/${USER_NAME}/avro \
        -w /home/${USER_NAME}/avro \
        -v ${HOME}/.m2:/home/${USER_NAME}/.m2 \
        -v ${HOME}/.gnupg:/home/${USER_NAME}/.gnupg \
        -u ${USER_NAME} \
        avro-build-${USER_NAME}
      ;;

    rat)
      mvn test -Dmaven.main.skip=true -Dmaven.test.skip=true -DskipTests=true -P rat -pl :avro-toplevel
      ;;

    *)
      usage
      ;;
  esac

done

exit 0
