#!/usr/bin/env python3
# FIXME: Remove before the release

import os.path
import re
import sys

def process_comment(fd, comment, first_param, last_param):
    if first_param < 0:
        # Nothing to do: just copy the comment
        fd.write("".join(comment))
    else:
        params = list()

        # Copy the non param lines unmodified:
        fd.write("".join(comment[:first_param]))

        # Measure the indentation of the first param and use that to create an empty comment line string:
        m = re.match(r" *\*", comment[first_param])

        if not m:
            raise Exception("Not a comment ? '{}'".format(comment[first_param]))

        empty_line = "{}\n".format(m.group(0))

        # For each param split the line into 3 columns: param, param_name, description
        for param in range(first_param, last_param):
            m = re.match(r"([^@]+@param\[[^\]]+\]) +(\S+) +(.+)", comment[param])

            if m:
                params.append( (m.group(1), m.group(2), m.group(3)) )
            else:
                # If it's not a match then it must be a multi-line param description:

                m = re.match("( *\*) +(.*)", comment[param])

                if not m:
                    raise Exception("Not a comment line ? ({})".format(n_line - len(comment) + param))

                params.append( (m.group(1), "", m.group(2)) )

        # Now that we've got a list of params, find what is the longest string for each column:
        max_len = [0, 0]

        for p in params:
            for l in range(len(max_len)):
                max_len[l] = max(max_len[l], len(p[l]))

        # Insert an empty line if needed before the first param to make it easier to read:
        m = re.match(r" *\* *$", comment[first_param - 1])

        if not m:
            # insert empty line
            fd.write(empty_line)

        # Write out the formatted list of params:
        for p in params:
            fd.write("{}{} {}{} {}\n".format(
                    p[0], " " * (max_len[0] - len(p[0])),
                    p[1], " " * (max_len[1] - len(p[1])),
                    p[2]))

        # If the next line after the list of params is a command (@return, @note, @warning, etc), insert an empty line to separate it from the list of params
        if last_param < len(comment) - 1:
            if re.match(r" *\* *@\w+", comment[last_param]):
                # insert empty line
                fd.write(empty_line)

        # Copy the remaining of the comment unmodified:
        fd.write("".join(comment[last_param:]))

if __name__ == "__main__":
    n_file=0

    if len(sys.argv) == 1:
        paths = []

        for top_level in ["./arm_compute", "./src", "./examples", "./tests", "./utils", "./framework", "./support"]:
            for root, _, files in os.walk(top_level):
                paths.extend([os.path.join(root, f) for f in files])
    else:
        paths = sys.argv[1:]

    for path in paths:
        if (path[-3:] not in ("cpp", "inl") and
            path[-2:] not in ("cl") and
            path[-2:] not in ("cs") and
            path[-1] not in ("h")):
            continue

        print("[{}] {}".format(n_file, path))

        n_file += 1

        with open(path,'r+', encoding="utf-8") as fd:
            comment = list()
            first_param = -1
            last_param = -1
            n_line = 0

            lines = fd.readlines()
            fd.seek(0)
            fd.truncate()

            for line in lines:
                n_line += 1

                # Start comment
                # Match C-style comment /* anywhere in the line
                if re.search(r"/\*", line):
                    #print("Start comment {}".format(n_line))

                    if len(comment) > 0:
                        raise Exception("Already in a comment! ({})".format(n_line))

                    comment.append(line)

                # Comment already started
                elif len(comment) > 0:
                    #print("Add line to comment {}".format(n_line))

                    comment.append(line)

                # Non-comment line
                else:
                    #print("Normal line {}".format(n_line))

                    fd.write(line)

                # Match param declaration in Doxygen comment
                # @param[in] name description
                if re.search(r"@param\[[^\]]+\] +\S+ +\S", line):
                    #print("Param {}".format(n_line))

                    if first_param < 0:
                        first_param = len(comment) - 1

                    last_param = len(comment)

                # Match end of C-style comment */
                if re.search(r"\*/", line):
                    if re.search('"[^"]*\*/[^"]*"', line):
                        #print("End of comment inside a string: ignoring")
                        pass
                    else:
                        #print("End comment {}".format(n_line))

                        if len(comment) < 1:
                            raise Exception("Was not in a comment! ({})".format(n_line))

                        #print("Process comment {} {}".format(first_param, last_param))

                        process_comment(fd, comment, first_param, last_param)

                        comment = list()
                        first_param = -1
                        last_param = -1
