#!/bin/bash
#
# Copyright 2015 Google Inc. All rights reserved
#
# Licensed 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.
#
# A wrapper for kati which generates build.ninja mainly for Android.
#

set -e

kati_dir=$(cd $(dirname $0) && pwd)
extra_flags=
goma_flag=
goma_dir=${GOMA_DIR:-$HOME/goma}

while [ x"$1" != x"" ]; do
  case "$1" in
    --help)
      cat - <<EOF
Usage:
  m2n               # for default full-build
  m2n --goma        # use goma. \$HOME/goma must exist, or set \$GOMA_DIR
  m2n --go          # use go version. Slower but maybe more portable.
  m2n cts           # for target 'cts'
EOF
      exit 1
      ;;

    --go)
      kati=${kati_dir}/kati
      shift
      ${kati} --m2n "$@"
      echo
      echo ninja.sh and build.ninja were generated, please run ./ninja.sh
      exit
      ;;

    --goma)
      if [ ! -e $goma_dir/goma_ctl.py ]; then
        echo "To use Goma you must set GOMA_DIR, or install goma in $HOME/goma"
        exit 1
      fi
      $goma_dir/goma_ctl.py ensure_start
      goma_flag=--goma_dir=$goma_dir
      shift
      ;;

    --mmm)
      echo 'Note: --mmm may not work'
      shift;
      mmm="$1"
      shift
      ;;

    --lunch)
      shift;
      lunch="$1"
      extra_flags+=" --error_on_env_change"
      shift
      ;;

    -*)
      extra_flags+=" $1"
      shift
      ;;

    *)
      targets="${targets} $1"
      shift
      ;;
  esac
done

if [ x"${goma_flag}" != x ]; then
  for k in CC_WRAPPER CXX_WRAPPER JAVAC_WRAPPER; do
    val=$(eval echo \$$k)
    if [ x"${val}" != x ]; then
      echo "Note: \$$k=${val} may confuse m2n --goma, unsetting"
      unset $k
    fi
  done
fi

kati=${kati_dir}/ckati

ninja_suffix=
ninja_suffix_flag=

if [ x"${lunch}" != x"" ]; then
  source build/envsetup.sh
  lunch ${lunch}
  ninja_suffix=-${lunch}
fi

if [ x"${mmm}" != x"" ]; then
  mk="${mmm}/Android.mk"
  if [ ! -f ${mk} ]; then
    echo "${mk} does not exist"
    exit 1
  fi

  export ONE_SHOT_MAKEFILE=${mk}
  echo ONE_SHOT_MAKEFILE=${ONE_SHOT_MAKEFILE}

  ninja_suffix+=-mmm-${mmm}
fi

if [ x"${targets}" != x"" ]; then
  ninja_suffix+=-$(echo ${targets} | sed 's/ /-/')
elif [ x"${mmm}" != x"" ]; then
  targets=all_modules
fi

if [ x"${ninja_suffix}" != x"" ]; then
  ninja_suffix=$(echo ${ninja_suffix} | sed 'y/\//_/')
  ninja_suffix_flag=--ninja_suffix=${ninja_suffix}
fi

if [ x"${lunch}" != x"" ]; then
  printconfig | grep -v '^=' > .kati_lunch${ninja_suffix}
fi

${kati} --ninja ${ninja_suffix_flag} --ignore_optional_include=out/%.P --use_find_emulator --detect_android_echo ${goma_flag} ${extra_flags} ${targets}

echo
echo ninja${ninja_suffix}.sh and build${ninja_suffix}.ninja were generated, please run ./ninja${ninja_suffix}.sh
