#!/usr/bin/env python3
#
# ===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===------------------------------------------------------------------------===#

"""
This script reads input from a unified diff and reformats all the changed
lines. This is useful to reformat all the lines touched by a specific patch.
Example usage for git/svn users:

  git diff -U0 --no-color --relative HEAD^ | {clang_format_diff} -p1 -i
  svn diff --diff-cmd=diff -x-U0 | {clang_format_diff} -i

It should be noted that the filename contained in the diff is used unmodified
to determine the source file to update. Users calling this script directly
should be careful to ensure that the path in the diff is correct relative to the
current working directory.
"""
from __future__ import absolute_import, division, print_function

import argparse
import difflib
import re
import subprocess
import sys

if sys.version_info.major >= 3:
    from io import StringIO
else:
    from io import BytesIO as StringIO


def main():
    parser = argparse.ArgumentParser(
        description=__doc__.format(clang_format_diff="%(prog)s"),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "-i",
        action="store_true",
        default=False,
        help="apply edits to files instead of displaying a diff",
    )
    parser.add_argument(
        "-p",
        metavar="NUM",
        default=0,
        help="strip the smallest prefix containing P slashes",
    )
    parser.add_argument(
        "-regex",
        metavar="PATTERN",
        default=None,
        help="custom pattern selecting file paths to reformat "
        "(case sensitive, overrides -iregex)",
    )
    parser.add_argument(
        "-iregex",
        metavar="PATTERN",
        default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
        r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|ipynb|s?vh?)",
        help="custom pattern selecting file paths to reformat "
        "(case insensitive, overridden by -regex)",
    )
    parser.add_argument(
        "-sort-includes",
        action="store_true",
        default=False,
        help="let clang-format sort include blocks",
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        help="be more verbose, ineffective without -i",
    )
    parser.add_argument(
        "-style",
        help="formatting style to apply (LLVM, GNU, Google, Chromium, "
        "Microsoft, Mozilla, WebKit)",
    )
    parser.add_argument(
        "-fallback-style",
        help="The name of the predefined style used as a"
        "fallback in case clang-format is invoked with"
        "-style=file, but can not find the .clang-format"
        "file to use.",
    )
    parser.add_argument(
        "-binary",
        default="clang-format",
        help="location of binary to use for clang-format",
    )
    args = parser.parse_args()

    # Extract changed lines for each file.
    filename = None
    lines_by_file = {}
    for line in sys.stdin:
        match = re.search(r"^\+\+\+\ (.*?/){%s}(.+)" % args.p, line.rstrip())
        if match:
            filename = match.group(2)
        if filename is None:
            continue

        if args.regex is not None:
            if not re.match("^%s$" % args.regex, filename):
                continue
        else:
            if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
                continue

        match = re.search(r"^@@.*\+(\d+)(?:,(\d+))?", line)
        if match:
            start_line = int(match.group(1))
            line_count = 1
            if match.group(2):
                line_count = int(match.group(2))
                # The input is something like
                #
                # @@ -1, +0,0 @@
                #
                # which means no lines were added.
                if line_count == 0:
                    continue
            # Also format lines range if line_count is 0 in case of deleting
            # surrounding statements.
            end_line = start_line
            if line_count != 0:
                end_line += line_count - 1
            lines_by_file.setdefault(filename, []).extend(
                ["--lines", str(start_line) + ":" + str(end_line)]
            )

    # Reformat files containing changes in place.
    has_diff = False
    for filename, lines in lines_by_file.items():
        if args.i and args.verbose:
            print("Formatting {}".format(filename))
        command = [args.binary, filename]
        if args.i:
            command.append("-i")
        if args.sort_includes:
            command.append("--sort-includes")
        command.extend(lines)
        if args.style:
            command.extend(["--style", args.style])
        if args.fallback_style:
            command.extend(["--fallback-style", args.fallback_style])

        try:
            p = subprocess.Popen(
                command,
                stdout=subprocess.PIPE,
                stderr=None,
                stdin=subprocess.PIPE,
                universal_newlines=True,
            )
        except OSError as e:
            # Give the user more context when clang-format isn't
            # found/isn't executable, etc.
            raise RuntimeError(
                'Failed to run "%s" - %s"' % (" ".join(command), e.strerror)
            )

        stdout, _stderr = p.communicate()
        if p.returncode != 0:
            return p.returncode

        if not args.i:
            with open(filename) as f:
                code = f.readlines()
            formatted_code = StringIO(stdout).readlines()
            diff = difflib.unified_diff(
                code,
                formatted_code,
                filename,
                filename,
                "(before formatting)",
                "(after formatting)",
            )
            diff_string = "".join(diff)
            if len(diff_string) > 0:
                has_diff = True
                sys.stdout.write(diff_string)

    if has_diff:
        return 1


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