#!/bin/bash
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

function get_build_dir {
  (source "${vars_sh}" && fx-config-read-if-present && echo "${FUCHSIA_BUILD_DIR}")
}

function commands {
  local cmds="$(ls "${fuchsia_dir}/scripts/devshell" | grep -v -e '^lib$' -e '^tests$')"

  local newline=$'\n'
  local build_dir=$(get_build_dir)
  if [[ -n "${build_dir}" ]]; then
    cmds="${cmds}${newline}$(ls "${build_dir}/tools" 2>/dev/null)"
  fi

  for tool in ${buildtools_whitelist}; do
    cmds="${cmds}${newline}${tool}"
  done

  echo "$(echo "${cmds}" | sort)"
}

function find_command {
  local cmd=$1

  local command_path="${fuchsia_dir}/scripts/devshell/${cmd}"
  if [[ -x "${command_path}" ]]; then
    echo "${command_path}"
    return 0
  fi

  local build_dir=$(get_build_dir)
  if [[ -n "${build_dir}" ]]; then
    local command_path="${build_dir}/tools/${cmd}"
    if [[ -x "${command_path}" ]]; then
      echo "${command_path}"
      return 0
    fi
  fi

  for tool in ${buildtools_whitelist}; do
    if [[ "$cmd" != "$tool" ]]; then
      continue
    fi
    local command_path="${fuchsia_dir}/buildtools/${tool}"
    if [[ -x "${command_path}" ]]; then
      echo "${command_path}"
      return 0
    fi
  done

  return 1
}

function help {
  local cmd="$1"
  if [[ -z "${cmd}" ]]; then
    for cmd in $(commands); do
      local cmd_path="$(find_command "${cmd}")"
      if [[ $(file -b --mime "${cmd_path}" | cut -d / -f 1) == "text" ]]; then
        echo "${cmd} | $(sed -n '1,/^###/s/^### //p' < "${cmd_path}")"
      else
        echo "${cmd}"
      fi
    done | column -t -s '|' -c 2
  else
    local cmd_path="$(find_command "${cmd}")"
    if [[ -z "$cmd_path" ]]; then
      echo "Command not found"
    elif [[ $(file -b --mime "${cmd_path}" | cut -d / -f 1) == "text" ]]; then
      fx-print-command-help "${cmd_path}"
    else
      echo "No help found. Try \`fx ${cmd} -h\`"
    fi
  fi
}

function usage {
  cat <<END
usage: fx [--config CONFIG_FILE | --dir BUILD_DIR] [-d DEVICE_NAME] [-i] [-x] COMMAND [...]

Run Fuchsia development commands. Must be run with either a current working
directory that is contained in a Fuchsia source tree or the FUCHSIA_DIR
environment variable set to the root of a Fuchsia source tree.

commands:
$(help)

optional arguments:
  --config=CONFIG_FILE  Path to the config file use when running COMMAND.
                        Defaults to FUCHSIA_CONFIG if set in the
                        environment and //.config otherwise.  The config
                        file determines which build directory (and therefore
                        build configuration) is used by COMMAND.
  --dir=BUILD_DIR       Path to the build directory to use when running COMMAND.
                        If specified, FILE is ignored.
  -d=DEVICE_NAME        Target a specific device. DEVICE_NAME may be a Fuchsia
                        device name. Note: "fx set-device" can be used to set a
                        default DEVICE_NAME for a BUILD_DIR.
  -i                    Iterative mode.  Repeat the command whenever a file is
                        modified under your Fuchsia directory, not including
                        out/.
  -x                    Print commands and their arguments as they are executed.

optional shell extensions:
  fx-go
  fx-update-path
  fx-set-prompt

To use these shell extensions, first source fx-env.sh into your shell:

  $ source scripts/fx-env.sh

END
}

buildtools_whitelist="gn ninja"

fuchsia_dir="${FUCHSIA_DIR}"
if [[ -z "${fuchsia_dir}" ]]; then
  # We walk the parent directories looking for .jiri_root rather than using
  # BASH_SOURCE so that we find the fuchsia_dir enclosing the current working
  # directory instead of the one containing this file in case the user has
  # multiple Fuchsia source trees and is picking up this file from another one.
  fuchsia_dir="$(pwd)"
  while [[ ! -d "${fuchsia_dir}/.jiri_root" ]]; do
    fuchsia_dir="$(dirname "${fuchsia_dir}")"
    if [[ "${fuchsia_dir}" == "/" ]]; then
      echo >& 2 "error: Cannot find Fuchsia source tree containing $(pwd)"
      exit 1
    fi
  done
fi

declare -r vars_sh="${fuchsia_dir}/scripts/devshell/lib/vars.sh"
source "${vars_sh}" || exit $?

while [[ $# -ne 0 ]]; do
  case $1 in
    --config=*|--dir=*|-d=*)
      # Turn --switch=value into --switch value.
      arg="$1"
      shift
      set -- "${arg%%=*}" "${arg#*=}" "$@"
      continue
      ;;
    --config)
      if [[ $# -lt 2 ]]; then
        usage
        echo >&2 "ERROR: Missing path to config file for --config argument"
        exit 1
      fi
      shift # Removes --config.
      export FUCHSIA_CONFIG="$1"
      ;;
    --dir)
      if [[ $# -lt 2 ]]; then
        usage
        echo >&2 "ERROR: Missing path to build directory for --dir argument"
        exit 1
      fi
      shift # Removes --dir.
      export FUCHSIA_BUILD_DIR="$1"
      if [[ "$FUCHSIA_BUILD_DIR" == //* ]]; then
        FUCHSIA_BUILD_DIR="${fuchsia_dir}/${FUCHSIA_BUILD_DIR#//}"
      fi
      if [[ ! -d "$FUCHSIA_BUILD_DIR" ]]; then
        echo >&2 "ERROR: Build directory $FUCHSIA_BUILD_DIR does not exist"
        exit 1
      fi
      # This tells fx-config-read not to use the file.
      export FUCHSIA_CONFIG=-
      ;;
    -d)
      if [[ $# -lt 2 ]]; then
        usage
        echo >&2 "ERROR: Missing device name for -d argument"
        exit 1
      fi
      shift # removes -d
      export FUCHSIA_DEVICE_NAME="$1"
      ;;
    -i)
      declare iterative=1
      ;;
    -x)
      export FUCHSIA_DEVSHELL_VERBOSITY=1
      ;;
    --)
      shift
      break
      ;;
    help)
      if [[ $# -gt 1 ]]; then
        shift
        help "$@"
        exit
      else
        usage
        exit 1
      fi
      ;;
    -*)
      usage
      echo >& 2 "error: Unknown global argument $1"
      exit 1
      ;;
    *)
      break
      ;;
  esac
  shift
done

if [[ $# -lt 1 ]]; then
  usage
  echo >& 2 "error: Missing command name"
  exit 1
fi

command_name="$1"
command_path="$(find_command ${command_name})"

if [[ $? -ne 0 ]]; then
  usage
  echo >& 2 "error: Unknown command ${command_name}"
  exit 1
fi

declare -r cmd_and_args="$@"
shift # Removes the command name.

"${command_path}" "$@"
declare -r retval=$?
if [ -z "${iterative}" ]; then
  exit ${retval}
elif which inotifywait >/dev/null; then
  # Watch everything except out/ and files/directories beginning with "."
  # such as lock files, swap files, .git, etc'.
  inotifywait -qrme modify --exclude "(/\.|lock|compile_commands.json)" "${fuchsia_dir}" @"${fuchsia_dir}"/out @"${fuchsia_dir}"/zircon/public | while read; do
    # Drain all subsequent events in a batch.
    # Otherwise when multiple files are changes at once we'd run multiple
    # times.
    read -d "" -t .01
    # Allow at most one fx -i invocation per Fuchsia dir at a time.
    # Otherwise multiple concurrent fx -i invocations can trigger each other
    # and cause a storm.
    echo "---------------------------------- fx -i ${cmd_and_args} ---------------------------------------"
    "${command_path}" "$@"
    echo "--- Done!"
  done
elif which apt-get >/dev/null; then
  echo "Missing inotifywait"
  echo "Try: sudo apt-get install inotify-tools"
elif which fswatch >/dev/null; then
  fswatch --one-per-batch --event=Updated -e "${fuchsia_dir}"/out/ -e "${fuchsia_dir}"/zircon/public/ -e "/\." -e "lock" -e "/compile_commands.json" . | while read; do
    echo "---------------------------------- fx -i ${cmd_and_args} ---------------------------------------"
    "${command_path}" "$@"
    echo "--- Done!"
  done
else
  echo "Missing fswatch"
  echo "Try: brew install fswatch"
fi
