#!/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.RunCommand(cmd=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.RunCommand(cmd=cmd,
                                       print_cmd=False,
                                       redirect_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.output
  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.RunCommand(cmd=['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)
