#!/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` 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}" ;;
      *.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 --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}/prebuilt/third_party/dart/${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 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
