#!/bin/bash
# Copyright 2018 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.

#### CATEGORY=Source tree
### runs source formatters on modified files

## Usage: fx format-code
##           [--dry-run] [--verbose] [--all]
##           [--files=FILES,[FILES ...]]
##           [--target=GN_TARGET]
##           [--git] [-- PATTERN]
##
##   --dry-run Stops the program short of running the formatters
##   --all     Formats all code in the git repo under the current working
##             directory.
##   --files   Allows the user to specify files.  Files are comma separated.
##             Globs are dealt with by bash; fx format-code "--files=foo/*" will
##             work as expected.
##   --target  Allows the user to specify a gn target.
##   --git     The default; it uses `git diff` against the newest parent
##             commit in the upstream branch (or against HEAD if no such commit
##             is found).  Files that are locally modified, staged or touched by
##             any commits introduced on the local branch are formatted.
##    -- PATTERN
##             For --all or --git, passes along -- PATTERN to `git ls-files`
##             to filter what files are affected.

set -e

source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../lib/vars.sh || exit $?

function usage() {
  fx-command-help
}

function zap-commas() {
  echo $1 | tr ',' '\n'
}

function get-diff-base() {
  local upstream=$(git rev-parse --abbrev-ref --symbolic-full-name "@{u}" 2>/dev/null)
  if [[ -z "${upstream}" ]]; then
    upstream="origin/master"
  fi
  local local_commit=$(git rev-list HEAD ^${upstream} --  2>/dev/null | tail -1)
  if [[ -z "${local_commit}" ]]; then
    printf "HEAD"
  else
    git rev-parse "${local_commit}"^
  fi
}

function format-cmd() {
  if [ -f "$1" ]; then
    case "$1" in
      *.c | *.cc | *.cpp | *.h | *.hh | *.hpp | *.proto | *.ts)
        printf "${CLANG_CMD}" ;;

      *.cmx) printf "${JSON_FMT_CMD}" ;;
      *.dart) printf "${DART_CMD}" ;;
      *.fidl) printf "${FIDL_CMD}" ;;
      *.gn) printf "${GN_CMD}" ;;
      *.gni) printf "${GN_CMD}" ;;
      *.go) printf "${GO_CMD}" ;;
      *.py) printf "${PY_CMD}" ;;
      *.rs) printf "${RUST_FMT_CMD}" ;;
    esac
  fi
}

function hg-cmd() {
  [[ $1 =~ .*\.h ]] && printf "${FIX_HEADER_GUARDS_CMD}"
}

# Removes leading //, resolves to absolute path, and resolves globs.  The first
# argument is a path prefix, and the remaining arguments are relative to that
# path prefix.
function canonicalize() {
  local root_dir="$1"
  shift
  for fileglob in "${@}"; do
    # // means it comes from gn, [^/]* means it is relative
    if [[ "${fileglob}" = //* || "${fileglob}" = [^/]* ]]; then
      local dir="${root_dir}"/
    else
      local dir=""
    fi
    for file in "${dir}"${fileglob#"//"}; do
      echo "${file}"
    done
  done
}

DRY_RUN=
VERBOSE=

fx-config-read

GET_FILES=get_git_files
while [ $# -gt 0 ]; do
  ARG="$1"
  case "$1" in
    --verbose) VERBOSE="1" ;;
    --dry-run) DRY_RUN="1" ;;
    --all) GET_FILES=get_all_files ;;
    --git) GET_FILES=get_git_files ;;
    --files=*)
      GET_FILES=:
      FILES=$(canonicalize "${PWD}" $(zap-commas "${ARG#--files=}"))
      ;;
    --target=*)
      GET_FILES=:
      FILES=$(canonicalize "${FUCHSIA_DIR}" \
        $(fx-gn desc \
            "${FUCHSIA_OUT_DIR}/${FUCHSIA_ARCH}" "${ARG#--target=}" sources)) &&
        RUST_ENTRY_POINT=$(canonicalize "${FUCHSIA_DIR}" \
            $(fx rustfmt --print-sources ${ARG#--target=})) ;;
    --) break ;;
    *) usage && printf "Unknown flag %s\n" "${ARG}" && exit 1 ;;
  esac
  shift
done
GIT_FILTER=("$@" :!third_party/rust_crates/vendor*)

get_git_files() {
  FILES=$(canonicalize $(git rev-parse --show-toplevel) \
    $(git diff --name-only $(get-diff-base) "${GIT_FILTER[@]}"))
}

get_all_files() {
  FILES=$(canonicalize "${PWD}" $(git ls-files "${GIT_FILTER[@]}"))
}

$GET_FILES

# Do not format these files
NO_FORMAT=(
  # fxb/46090
  "${FUCHSIA_DIR}/build/unification/images/BUILD.gn"
  "${FUCHSIA_DIR}/build/unification/tests/host/BUILD.gn"
  "${FUCHSIA_DIR}/zircon/system/banjo/BUILD.gn"
  "${FUCHSIA_DIR}/zircon/system/fidl/BUILD.gn"
  "${FUCHSIA_DIR}/zircon/system/utest/BUILD.gn"
)

for to_remove in "${NO_FORMAT[@]}"; do
  FILES=("${FILES[@]//$to_remove}")
done

if [[ -n "${VERBOSE}" ]]; then
  printf "Files to be formatted:\n%s\n" "${FILES[@]}"
fi

declare CLANG_CMD="${PREBUILT_CLANG_DIR}/bin/clang-format -style=file -fallback-style=Google -sort-includes -i"
declare DART_CMD="${PREBUILT_DART_DIR}/bin/dartfmt -w"
declare FIDL_BIN="${ZIRCON_TOOLS_DIR}"/fidl-format
declare FIDL_CMD="${FIDL_BIN} -i"
declare GN_CMD="${PREBUILT_GN} format"
declare GO_CMD="${PREBUILT_GO_DIR}/bin/gofmt -s -w"
declare JSON_FMT_CMD="${FUCHSIA_DIR}"/scripts/style/json-fmt.py
declare PY_CMD="${FUCHSIA_DIR}/prebuilt/third_party/vpython/vpython ${FUCHSIA_DIR}/prebuilt/third_party/yapf/yapf --in-place"
declare RUST_FMT_CMD="${PREBUILT_RUST_DIR}/bin/rustfmt --config-path=${FUCHSIA_DIR}/rustfmt.toml --unstable-features --skip-children"
declare RUST_ENTRY_POINT_FMT_CMD="${PREBUILT_RUST_DIR}/bin/rustfmt --config-path=${FUCHSIA_DIR}/rustfmt.toml"

declare FIX_HEADER_GUARDS_CMD="${FUCHSIA_DIR}/scripts/style/check-header-guards.py --fix"

# If there is a FIDL file to fix, and we don't have a copy of fidl-format,
# generate one.
for file in "${FILES[@]}"; do
  if [[ ${file} =~ .*\.fidl ]]; then
    if [[ ! -x "${FIDL_BIN}" ]]; then
       printf "fidl-format not found: attempting to build it\n"
       fx-command-run build system/fidl:tools
       break
     fi
  fi
done

[[ -n "${DRY_RUN}" ]] && exit

[[ -n "${RUST_ENTRY_POINT}" ]] && ${RUST_ENTRY_POINT_FMT_CMD} "${RUST_ENTRY_POINT}"

for file in ${FILES[@]}; do
  # Git reports deleted files, which we don't want to try to format
  [[ ! -f "${file}" ]] && continue

  # Format the file
  declare fcmd=$(format-cmd ${file})
  [[ -n "${fcmd}" ]] && ${fcmd} "${file}"
  declare hgcmd=$(hg-cmd ${file})
  [[ -n "${hgcmd}" ]] && ${hgcmd} "${file}"
done

# The last thing this script does is often the [[ -n "${hgcmd}" ]], which will
# often return a non-zero value.  So, we force the script to return 0 and rely
# on "set -e" to catch real errors.
exit 0
