#!/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()
