#!/usr/bin/env python2.7
# Copyright 2015 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Change comments style of source files from // to /** */"""

import re
import sys

if len(sys.argv) < 2:
    print("Please provide at least one source file name as argument.")
    sys.exit()

for file_name in sys.argv[1:]:

    print("Modifying format of {file} comments in place...".format(
        file=file_name,))

    # Input

    with open(file_name, "r") as input_file:
        lines = input_file.readlines()

    def peek():
        return lines[0]

    def read_line():
        return lines.pop(0)

    def more_input_available():
        return lines

    # Output

    output_lines = []

    def write(line):
        output_lines.append(line)

    def flush_output():
        with open(file_name, "w") as output_file:
            for line in output_lines:
                output_file.write(line)

    # Pattern matching

    comment_regex = r'^(\s*)//\s(.*)$'

    def is_comment(line):
        return re.search(comment_regex, line)

    def isnt_comment(line):
        return not is_comment(line)

    def next_line(predicate):
        return more_input_available() and predicate(peek())

    # Transformation

    def indentation_of(line):
        match = re.search(comment_regex, line)
        return match.group(1)

    def content(line):
        match = re.search(comment_regex, line)
        return match.group(2)

    def format_as_block(comment_block):
        if len(comment_block) == 0:
            return []

        indent = indentation_of(comment_block[0])

        if len(comment_block) == 1:
            return [indent + "/** " + content(comment_block[0]) + " */\n"]

        block = ["/**"] + [" * " + content(line) for line in comment_block
                          ] + [" */"]
        return [indent + line.rstrip() + "\n" for line in block]

    # Main algorithm

    while more_input_available():
        while next_line(isnt_comment):
            write(read_line())

        comment_block = []
        # Get all lines in the same comment block. We could restrict the indentation
        # to be the same as the first line of the block, but it's probably ok.
        while (next_line(is_comment)):
            comment_block.append(read_line())

        for line in format_as_block(comment_block):
            write(line)

    flush_output()
