#!/usr/bin/env vpython3
# Copyright 2015 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Script to apply fixits generated by clang. This is to work around the fact
# that clang's -Xclang -fixit-recompile flag, which automatically applies fixits
# and recompiles, doesn't work well with parallel invocations of clang.
#
# Usage:
# 1. Enable parseable fixits and disable warnings as errors. Instructions for
#    doing this vary based on the build environment, but for GN, warnings as
#    errors can be disabled by setting treat_warnings_as_errors = false
#    Enabling parseable fixits requires editing build/config/compiler/BUILD.gn
#    and adding `-fdiagnostics-parseable-fixits` to cflags.
# 2. Build everything and capture the output:
#      ninja -C <build_directory> &> generated-fixits
# 3. Apply the fixits with this script:
#      python apply_fixits.py -p <build_directory> < generated-fixits

from __future__ import print_function

import argparse
import collections
import fileinput
import os
import re
import sys

# fix-it:"../../base/threading/sequenced_worker_pool.h":{341:3-341:11}:""
# Note that the file path is relative to the build directory.
_FIXIT_RE = re.compile(r'^fix-it:"(?P<file>.+?)":'
                       r'{(?P<start_line>\d+?):(?P<start_col>\d+?)-'
                       r'(?P<end_line>\d+?):(?P<end_col>\d+?)}:'
                       r'"(?P<text>.*?)"$')

FixIt = collections.namedtuple(
    'FixIt', ('start_line', 'start_col', 'end_line', 'end_col', 'text'))


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-p',
      required=True,
      help='path to the build directory to complete relative paths in fixits')
  args = parser.parse_args()

  fixits = collections.defaultdict(list)
  for line in fileinput.input(['-']):
    if not line.startswith('fix-it:'):
      continue
    m = _FIXIT_RE.match(line)
    if not m:
      continue
    # The negative line numbers are a cheap hack so we can sort things in line
    # order but reverse column order. Applying the fixits in reverse order makes
    # things simpler, since offsets won't have to be adjusted as the text is
    # changed.
    fixits[m.group('file')].append(FixIt(
        int(m.group('start_line')), -int(m.group('start_col')), int(m.group(
            'end_line')), -int(m.group('end_col')), m.group('text')))
  for k, v in fixits.iteritems():
    v.sort()
    with open(os.path.join(args.p, k), 'rb+') as f:
      lines = f.readlines()
      last_fixit = None
      for fixit in v:
        if fixit.start_line != fixit.end_line:
          print('error: multiline fixits not supported! file: %s, fixit: %s' %
                (k, fixit))
          sys.exit(1)
        if fixit == last_fixit:
          continue
        last_fixit = fixit
        # The line/column numbers emitted in fixit hints start at 1, so offset
        # is appropriately.
        line = lines[fixit.start_line - 1]
        lines[fixit.start_line - 1] = (line[:-fixit.start_col - 1] + fixit.text
                                       + line[-fixit.end_col - 1:])
      f.seek(0)
      f.truncate()
      f.writelines(lines)


if __name__ == '__main__':
  sys.exit(main())
