#
# Copyright (c) 2020 Arm Limited.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#
#!/usr/bin/env python
import re
import os
import sys
import argparse
import fnmatch
import logging

import json
import glob

logger = logging.getLogger("acl_tracing")

# Returns the files matching the given pattern
def find(path, pattern):
    matches = []
    for root, dirnames, filenames, in os.walk(path):
        for filename in fnmatch.filter(filenames, pattern):
            matches.append(os.path.join(root,filename))
    return matches

# Returns the class name (Core or Runtime) and arguments of the given function
def get_class_and_args(function):
    decl = " ".join(function_signature)
    m = re.match("void ([^:]+)::configure\(([^)]*)\)", decl)
    if m:
            assert m, "Can't parse '%s'" % line
            class_name = m.group(1)
            args = m.group(2)
            #Remove comments:
            args = re.sub("\/\*.*?\*\/","",args)
            #Remove templates
            args = re.sub("<.*?>","",args)
            logger.debug(args)
            arg_names = []
            for arg in args.split(","):
                m = re.match(".*?([^ &*]+)$", arg.strip())
                arg_names.append(m.group(1))
                logger.debug("  %s" % m.group(1))
            return (class_name, arg_names)
    else:
        return ('','')

# Adds the tracepoints to the source file for the given function
def do_insert_tracing(source, function, fd):
    logger.debug("Full signature = %s" % " ".join(function_signature))
    class_name, arg_names = get_class_and_args(function)
    if len(arg_names):
        assert len(arg_names), "No argument to configure for %s ?" % class_name
        spaces = re.match("([ ]*)void", function[0]).group(1)
        fd.write("%s    CREATE_TRACEPOINT(%s, \"%s\", this, TracePoint::Args()" % (spaces, source, class_name))
        for arg in arg_names:
            fd.write("<<%s" % arg)
        fd.write(");\n")
    else:
        print('Failed to get class name in %s ' % " ".join(function_signature))


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
            formatter_class=argparse.RawDescriptionHelpFormatter,
            description="Post process JSON benchmark files",
    )

    parser.add_argument("-D", "--debug", action='store_true', help="Enable script debugging output")
    args = parser.parse_args()
    logging_level = logging.INFO
    if args.debug:
        logging_level = logging.DEBUG
    logging.basicConfig(level=logging_level)
    logger.debug("Arguments passed: %s" % str(args.__dict__))
    for f in find("src","*.cpp"):
        logger.debug(f)
        fd = open(f,'r+')
        lines = fd.readlines()
        contains_configure = False
        for line in lines:
            if re.search(r"void.*::configure\(",line):
                contains_configure = True
                break
        if not contains_configure:
            continue
        fd.seek(0)
        fd.truncate()
        function_signature = None
        insert_tracing = False
        start = True
        for line in lines:
            write = True
            if start:
                if not (line.startswith("/*") or line.startswith(" *") or line.startswith("#") or len(line.strip()) == 0):
                    start = False
                    fd.write("#include \"arm_compute/core/TracePoint.h\"\n")
            elif not function_signature:
                if re.search(r"void.*::configure\(",line):
                    function_signature = [ line.rstrip() ]
            else:
                if re.search("[ ]*{$", line):
                    insert_tracing = True
                else:
                    function_signature.append(line.rstrip())
            if write:
                fd.write(line)
            if insert_tracing:
                if "/core/" in f:
                    source = "TracePoint::Layer::CORE"
                elif "/runtime/" in f:
                    source = "TracePoint::Layer::RUNTIME"
                else:
                    assert "Can't find layer for file %s" %f
                do_insert_tracing(source, function_signature, fd)
                insert_tracing = False
                function_signature = None
