#! /usr/bin/env 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.

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
   bin="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
   SOURCE="$(readlink "$SOURCE")"
   [[ $SOURCE != /* ]] && SOURCE="$bin/$SOURCE"
done
# Set up variables needed by fluo-env.sh
export bin="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
export basedir="$( cd -P ${bin}/.. && pwd )"
export conf="$basedir/conf"
export lib="$basedir/lib"
export cmd="$1"
case "$cmd" in
  start) export app="$2" ;;
esac
export FLUO_YARN_VERSION=@project.version@

if [ ! -f "$conf/fluo-yarn-env.sh" ]; then
  echo "fluo-yarn-env.sh must exist in $conf"
  exit 1
fi
source "$conf/fluo-yarn-env.sh"
export CLASSPATH=$LAUNCHER_CLASSPATH

# stop if any command fails
set -e

function print_usage {
  echo -e "Usage: fluo-yarn <command> (<argument> ...)\n"
  echo -e "Possible commands:\n"
  echo "  classpath                   Prints the classpath setup by fluo-yarn-env.sh"
  echo "  start <app> <yarnProps>     Starts Fluo <app> in YARN using <yarnProps>"
  echo "  version                     Prints the version of Fluo YARN launcher"
  echo " "
  exit 1
}

function build_bundled_jar {
  app_dir=$lib/apps/$app
  mkdir -p "$app_dir/lib"
  $FLUO_HOME/bin/fluo get-jars -a "$app" -d "$app_dir/lib"

  fluo_classpath=$FLUO_CLASSPATH

  IFS=':' read -ra ADDR <<< "$fluo_classpath"
  for cpentry in "${ADDR[@]}"; do
    if [[ $cpentry = *\* ]]; then
      for f in $cpentry; do
        if [[ -f $f ]]; then
          cp "$f" "$app_dir/lib/"
        fi
      done
    else
      cp "$cpentry" "$app_dir/lib/"
    fi
  done

  bundled_jar=fluo-app-${app}.jar

  pushd "$app_dir" > /dev/null
  jar cf $bundled_jar lib
  popd > /dev/null
}

case "$1" in
start)
  if [ ! -f "$FLUO_CONN_PROPS" ]; then
    echo "Fluo connection properties file '$FLUO_CONN_PROPS' does not exist"
    exit 1
  fi
  if [ ! -f "$3" ]; then
    echo "The file argument given for <yarnProps> does not exist at $3"
    print_usage
    exit 1
  fi
  app_status=$($FLUO_HOME/bin/fluo status -a $app)
  if [[ "$app_status" == "RUNNING" ]]; then
    echo "Fluo appplication '$app' is already running!"
    exit 1
  fi
  build_bundled_jar
  java org.apache.fluo.yarn.FluoYarnLauncher "$FLUO_CONN_PROPS" "$3" "$conf/log4j.properties" "$app" "$app_dir/$bundled_jar"
  ;;
classpath)
  echo "$CLASSPATH"
  ;;
version)
  echo "$FLUO_YARN_VERSION"
  ;;
*)
  print_usage
esac
