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

### 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-index` 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
      *.cc) printf "${CLANG_CMD}" ;;
      *.cmx) printf "${JSON_FMT_CMD}" ;;
      *.cpp) printf "${CLANG_CMD}" ;;
      *.dart) printf "${DART_CMD}" ;;
      *.fidl) printf "${FIDL_CMD}" ;;
      *.gn) printf "${GN_CMD}" ;;
      *.gni) printf "${GN_CMD}" ;;
      *.go) printf "${GO_CMD}" ;;
      *.h) printf "${CLANG_CMD}" ;;
      *.hh) printf "${CLANG_CMD}" ;;
      *.hpp) printf "${CLANG_CMD}" ;;
      *.ts) printf "${CLANG_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-buildtool-run 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=("$@")

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

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

$GET_FILES

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

declare BUILDTOOLS_ROOT="${FUCHSIA_DIR}"/buildtools
declare HOST_OS=$(uname | tr '[:upper:]' '[:lower:]')

[[ "${HOST_OS}" == "darwin" ]] && HOST_OS="mac"
case $(uname -m) in
  x86_64) HOST_ARCH="x64" ;;
  aarch64) HOST_ARCH="arm64" ;;
  *) echo "Unknown arch $(uname -m)" && exit 1 ;;
esac

declare HOST_PLATFORM="${HOST_OS}-${HOST_ARCH}"

declare CLANG_CMD="${BUILDTOOLS_ROOT}/${HOST_PLATFORM}/clang/bin/clang-format -style=file -fallback-style=Google -sort-includes -i"
declare DART_CMD="${FUCHSIA_DIR}/topaz/tools/prebuilt-dart-sdk/${HOST_PLATFORM}/bin/dartfmt -w"
declare FIDL_BIN="${ZIRCON_TOOLS_DIR}"/fidl-format
declare FIDL_CMD="${FIDL_BIN} -i"
declare GN_CMD="${BUILDTOOLS_ROOT}/gn format"
declare GO_CMD="${BUILDTOOLS_ROOT}/${HOST_PLATFORM}/go/bin/gofmt -s -w"
declare JSON_FMT_CMD="${FUCHSIA_DIR}"/scripts/style/json-fmt.py
declare RUST_FMT_CMD="${BUILDTOOLS_ROOT}/${HOST_PLATFORM}/rust/bin/rustfmt --config-path=${FUCHSIA_DIR}/rustfmt.toml --unstable-features --skip-children"
declare RUST_ENTRY_POINT_FMT_CMD="${BUILDTOOLS_ROOT}/${HOST_PLATFORM}/rust/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-zircon -T
       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
