#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Wrapper to run git-clang-format and parse its output."""

from __future__ import print_function

import hashlib
import io
import os
import sys

_path = os.path.realpath(__file__ + '/../../..')
if sys.path[0] != _path:
  sys.path.insert(0, _path)
del _path

# The sys.path monkey patching confuses the linter.
# pylint: disable=wrong-import-position
from chromite.lib import commandline
from chromite.lib import constants
from chromite.lib import cros_build_lib


# Since we're asking git-clang-format to print a diff, all modified filenames
# that have formatting errors are printed with this prefix.
DIFF_MARKER_PREFIX = '+++ b/'

BUILDTOOLS_PATH = os.path.join(constants.SOURCE_ROOT, 'src', 'chromium', 'src',
                               'buildtools')


def _GetSha1Hash(path):
  """Gets the SHA-1 hash of |path|, or None if the file does not exist."""
  if not os.path.exists(path):
    return None
  with open(path, 'rb') as f:
    m = hashlib.sha1()
    while True:
      buf = f.read(io.DEFAULT_BUFFER_SIZE)
      if not buf:
        break
      m.update(buf)
    return m.hexdigest()


def _GetDefaultClangFormatPath():
  """Gets the default clang-format binary path.

  This also ensures that the binary itself is up-to-date.
  """

  clang_format_path = os.path.join(BUILDTOOLS_PATH, 'linux64/clang-format')
  hash_file_path = os.path.join(BUILDTOOLS_PATH, 'linux64/clang-format.sha1')
  with open(hash_file_path, 'r') as f:
    expected_hash = f.read().strip()
  if expected_hash != _GetSha1Hash(clang_format_path):
    # See chromium/src/buildtools/clang_format/README.txt for more details.
    cmd = [os.path.join(constants.DEPOT_TOOLS_DIR,
                        'download_from_google_storage.py'), '-b',
           'chromium-clang-format', '-s', hash_file_path]
    cros_build_lib.run(cmd, print_cmd=False)
  return clang_format_path


def main(argv):
  """Checks if a project is correctly formatted with clang-format.

  Returns 1 if there are any clang-format-worthy changes in the project (or
  on a provided list of files/directories in the project), 0 otherwise.
  """

  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('--clang-format', default=_GetDefaultClangFormatPath(),
                      help='The path of the clang-format executable.')
  parser.add_argument('--git-clang-format',
                      default=os.path.join(BUILDTOOLS_PATH, 'clang_format',
                                           'script', 'git-clang-format'),
                      help='The path of the git-clang-format executable.')
  parser.add_argument('--style', metavar='STYLE', type=str, default='file',
                      help='The style that clang-format will use.')
  parser.add_argument('--extensions', metavar='EXTENSIONS', type=str,
                      help='Comma-separated list of file extensions to '
                           'format.')
  parser.add_argument('--fix', action='store_true',
                      help='Fix any formatting errors automatically.')

  scope = parser.add_mutually_exclusive_group(required=True)
  scope.add_argument('--commit', type=str, default='HEAD',
                     help='Specify the commit to validate.')
  scope.add_argument('--working-tree', action='store_true',
                     help='Validates the files that have changed from '
                          'HEAD in the working directory.')

  parser.add_argument('files', type=str, nargs='*',
                      help='If specified, only consider differences in '
                           'these files/directories.')

  opts = parser.parse_args(argv)

  cmd = [opts.git_clang_format, '--binary', opts.clang_format, '--diff']
  if opts.style:
    cmd.extend(['--style', opts.style])
  if opts.extensions:
    cmd.extend(['--extensions', opts.extensions])
  if not opts.working_tree:
    cmd.extend(['%s^' % opts.commit, opts.commit])
  cmd.extend(['--'] + opts.files)

  # Fail gracefully if clang-format itself aborts/fails.
  try:
    result = cros_build_lib.run(cmd, print_cmd=False, stdout=True,
                                encoding='utf-8', errors='replace')
  except cros_build_lib.RunCommandError as e:
    print('clang-format failed:\n' + str(e), file=sys.stderr)
    print('\nPlease report this to the clang team.', file=sys.stderr)
    return 1

  stdout = result.stdout
  if stdout.rstrip('\n') == 'no modified files to format':
    # This is always printed when only files that clang-format does not
    # understand were modified.
    return 0

  diff_filenames = []
  for line in stdout.splitlines():
    if line.startswith(DIFF_MARKER_PREFIX):
      diff_filenames.append(line[len(DIFF_MARKER_PREFIX):].rstrip())

  if diff_filenames:
    if opts.fix:
      cros_build_lib.run(['git', 'apply'], print_cmd=False, input=stdout)
    else:
      print('The following files have formatting errors:')
      for filename in diff_filenames:
        print('\t%s' % filename)
      print('You can run `%s --fix %s` to fix this' %
            (sys.argv[0],
             ' '.join(cros_build_lib.ShellQuote(arg) for arg in argv)))
      return 1

  return 0


if __name__ == '__main__':
  commandline.ScriptWrapperMain(lambda _: main)
