// Copyright (c) 2017, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

package main

import (
	"bytes"
	"io/ioutil"
	"os"
	"strings"
)

// convert_comments.go converts C-style block comments to C++-style line
// comments. A block comment is converted if all of the following are true:
//
//   * The comment begins after the first blank line, to leave the license
//     blocks alone.
//
//   * There are no characters between the '*/' and the end of the line.
//
//   * Either one of the following are true:
//
//     - The comment fits on one line.
//
//     - Each line the comment spans begins with N spaces, followed by '/*' for
//       the initial line or ' *' for subsequent lines, where N is the same for
//       each line.
//
// This tool is a heuristic. While it gets almost all cases correct, the final
// output should still be looked over and fixed up as needed.

// allSpaces returns true if |s| consists entirely of spaces.
func allSpaces(s string) bool {
	return strings.IndexFunc(s, func(r rune) bool { return r != ' ' }) == -1
}

// isContinuation returns true if |s| is a continuation line for a multi-line
// comment indented to the specified column.
func isContinuation(s string, column int) bool {
	if len(s) < column+2 {
		return false
	}
	if !allSpaces(s[:column]) {
		return false
	}
	return s[column:column+2] == " *"
}

// indexFrom behaves like strings.Index but only reports matches starting at
// |idx|.
func indexFrom(s, sep string, idx int) int {
	ret := strings.Index(s[idx:], sep)
	if ret < 0 {
		return -1
	}
	return idx + ret
}

// writeLine writes |line| to |out|, followed by a newline.
func writeLine(out *bytes.Buffer, line string) {
	out.WriteString(line)
	out.WriteByte('\n')
}

func convertComments(in []byte) []byte {
	lines := strings.Split(string(in), "\n")
	var out bytes.Buffer

	// Account for the trailing newline.
	if len(lines) > 0 && len(lines[len(lines)-1]) == 0 {
		lines = lines[:len(lines)-1]
	}

	// Find the license block separator.
	for len(lines) > 0 {
		line := lines[0]
		lines = lines[1:]
		writeLine(&out, line)
		if len(line) == 0 {
			break
		}
	}

	// inComment is true if we are in the middle of a comment.
	var inComment bool
	// comment is the currently buffered multi-line comment to convert. If
	// |inComment| is true and it is nil, the current multi-line comment is
	// not convertable and we copy lines to |out| as-is.
	var comment []string
	// column is the column offset of |comment|.
	var column int
	for len(lines) > 0 {
		line := lines[0]
		lines = lines[1:]

		var idx int
		if inComment {
			// Stop buffering if this comment isn't eligible.
			if comment != nil && !isContinuation(line, column) {
				for _, l := range comment {
					writeLine(&out, l)
				}
				comment = nil
			}

			// Look for the end of the current comment.
			idx = strings.Index(line, "*/")
			if idx < 0 {
				if comment != nil {
					comment = append(comment, line)
				} else {
					writeLine(&out, line)
				}
				continue
			}

			inComment = false
			if comment != nil {
				if idx == len(line)-2 {
					// This is a convertable multi-line comment.
					if idx >= column+2 {
						// |idx| may be equal to
						// |column| + 1, if the line is
						// a '*/' on its own. In that
						// case, we discard the line.
						comment = append(comment, line[:idx])
					}
					for _, l := range comment {
						out.WriteString(l[:column])
						out.WriteString("//")
						writeLine(&out, strings.TrimRight(l[column+2:], " "))
					}
					comment = nil
					continue
				}

				// Flush the buffered comment unmodified.
				for _, l := range comment {
					writeLine(&out, l)
				}
				comment = nil
			}
			idx += 2
		}

		// Parse starting from |idx|, looking for either a convertable
		// line comment or a multi-line comment.
		for {
			idx = indexFrom(line, "/*", idx)
			if idx < 0 {
				writeLine(&out, line)
				break
			}

			endIdx := indexFrom(line, "*/", idx)
			if endIdx < 0 {
				inComment = true
				if allSpaces(line[:idx]) {
					// The comment is, so far, eligible for conversion.
					column = idx
					comment = []string{line}
				}
				break
			}

			if endIdx != len(line)-2 {
				// Continue parsing for more comments in this line.
				idx = endIdx + 2
				continue
			}

			out.WriteString(line[:idx])

			// Google C++ style prefers two spaces before a
			// comment if it is on the same line as code,
			// but clang-format has been placing one space
			// for block comments. Fix this.
			if !allSpaces(line[:idx]) && line[idx-1] != '(' {
				if line[idx-1] != ' ' {
					out.WriteString("  ")
				} else if line[idx-2] != ' ' {
					out.WriteString(" ")
				}
			}

			out.WriteString("//")
			writeLine(&out, strings.TrimRight(line[idx+2:endIdx], " "))
			break
		}
	}

	return out.Bytes()
}

func main() {
	for _, arg := range os.Args[1:] {
		in, err := ioutil.ReadFile(arg)
		if err != nil {
			panic(err)
		}
		if err := ioutil.WriteFile(arg, convertComments(in), 0666); err != nil {
			panic(err)
		}
	}
}
