#!/usr/bin/env python
# Copyright (c) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import optparse
import re
import string
import sys

template_h = string.Template("""// Code generated from InspectorInstrumentation.idl

#ifndef ${file_name}_h
#define ${file_name}_h

${includes}

namespace blink {

${forward_declarations}

namespace InspectorInstrumentation {

$methods
} // namespace InspectorInstrumentation

} // namespace blink

#endif // !defined(${file_name}_h)
""")

template_inline = string.Template("""
inline void ${name}(${params_public})
{   ${fast_return}
    if (${condition})
        ${name}Impl(${params_impl});
}
""")

template_inline_forward = string.Template("""
inline void ${name}(${params_public})
{   ${fast_return}
    ${name}Impl(${params_impl});
}
""")

template_inline_returns_value = string.Template("""
inline ${return_type} ${name}(${params_public})
{   ${fast_return}
    if (${condition})
        return ${name}Impl(${params_impl});
    return ${default_return_value};
}
""")


template_cpp = string.Template("""// Code generated from InspectorInstrumentation.idl

#include "config.h"

${includes}

namespace blink {
${extra_definitions}

namespace InspectorInstrumentation {
$methods

} // namespace InspectorInstrumentation

} // namespace blink
""")

template_outofline = string.Template("""
${return_type} ${name}Impl(${params_impl})
{${impl_lines}
}""")

template_agent_call = string.Template("""
    if (${agent_class}* agent = ${agent_fetch})
        ${maybe_return}agent->${name}(${params_agent});""")

template_agent_call_timeline_returns_cookie = string.Template("""
    int timelineAgentId = 0;
    if (InspectorTimelineAgent* agent = agents->inspectorTimelineAgent()) {
        if (agent->${name}(${params_agent}))
            timelineAgentId = agent->id();
    }""")


template_instrumenting_agents_h = string.Template("""// Code generated from InspectorInstrumentation.idl

#ifndef InstrumentingAgentsInl_h
#define InstrumentingAgentsInl_h

#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"

namespace blink {

${forward_list}

class InstrumentingAgents : public RefCountedWillBeGarbageCollectedFinalized<InstrumentingAgents> {
    WTF_MAKE_NONCOPYABLE(InstrumentingAgents);
    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
    static PassRefPtrWillBeRawPtr<InstrumentingAgents> create()
    {
        return adoptRefWillBeNoop(new InstrumentingAgents());
    }
    ~InstrumentingAgents() { }
    void trace(Visitor*);
    void reset();

${accessor_list}

private:
    InstrumentingAgents();

${member_list}
};

}

#endif // !defined(InstrumentingAgentsInl_h)
""")

template_instrumenting_agent_accessor = string.Template("""
    ${class_name}* ${getter_name}() const { return ${member_name}; }
    void set${class_name}(${class_name}* agent) { ${member_name} = agent; }""")

template_instrumenting_agents_cpp = string.Template("""
InstrumentingAgents::InstrumentingAgents()
    : $init_list
{
}

void InstrumentingAgents::trace(Visitor* visitor)
{
    $trace_list
}

void InstrumentingAgents::reset()
{
    $reset_list
}""")



def match_and_consume(pattern, source):
    match = re.match(pattern, source)
    if match:
        return match, source[len(match.group(0)):].strip()
    return None, source


def load_model_from_idl(source):
    source = re.sub("//.*", "", source)  # Remove line comments
    source = re.sub("/\*(.|\n)*?\*/", "", source, re.MULTILINE)  # Remove block comments
    source = re.sub("\]\s*?\n\s*", "] ", source)  # Merge the method annotation with the next line
    source = source.strip()

    model = []

    while len(source):
        match, source = match_and_consume("interface\s(\w*)\s?\{([^\{]*)\}", source)
        if not match:
            sys.stderr.write("Cannot parse %s\n" % source[:100])
            sys.exit(1)
        model.append(File(match.group(1), match.group(2)))

    return model


class File:
    def __init__(self, name, source):
        self.name = name
        self.header_name = self.name + "Inl"
        self.includes = [include_inspector_header("InspectorInstrumentation")]
        self.forward_declarations = []
        self.declarations = []
        for line in map(str.strip, source.split("\n")):
            line = re.sub("\s{2,}", " ", line).strip()  # Collapse whitespace
            if len(line) == 0:
                continue
            if line[0] == "#":
                self.includes.append(line)
            elif line.startswith("class "):
                self.forward_declarations.append(line)
            else:
                self.declarations.append(Method(line))
        self.includes.sort()
        self.forward_declarations.sort()

    def generate(self, cpp_lines, used_agents):
        header_lines = []
        for declaration in self.declarations:
            for agent in set(declaration.agents):
                used_agents.add(agent)
            declaration.generate_header(header_lines)
            declaration.generate_cpp(cpp_lines)

        return template_h.substitute(None,
                                     file_name=self.header_name,
                                     includes="\n".join(self.includes),
                                     forward_declarations="\n".join(self.forward_declarations),
                                     methods="\n".join(header_lines))


class Method:
    def __init__(self, source):
        match = re.match("(\[[\w|,|=|\s]*\])?\s?(\w*\*?) (\w*)\((.*)\)\s?;", source)
        if not match:
            sys.stderr.write("Cannot parse %s\n" % source)
            sys.exit(1)

        self.options = []
        if match.group(1):
            options_str = re.sub("\s", "", match.group(1)[1:-1])
            if len(options_str) != 0:
                self.options = options_str.split(",")

        self.return_type = match.group(2)

        self.name = match.group(3)

        # Splitting parameters by a comma, assuming that attribute lists contain no more than one attribute.
        self.params = map(Parameter, map(str.strip, match.group(4).split(",")))

        self.accepts_cookie = len(self.params) and self.params[0].type == "const InspectorInstrumentationCookie&"
        self.returns_cookie = self.return_type == "InspectorInstrumentationCookie"

        self.returns_value = self.return_type != "void"

        if self.return_type == "bool":
            self.default_return_value = "false"
        elif self.return_type == "int":
            self.default_return_value = "0"
        elif self.return_type == "String":
            self.default_return_value = "\"\""
        else:
            self.default_return_value = self.return_type + "()"

        for param in self.params:
            if "DefaultReturn" in param.options:
                self.default_return_value = param.name

        self.params_impl = self.params
        if not self.accepts_cookie and not "Inline=Forward" in self.options:
            if not "Keep" in self.params_impl[0].options:
                self.params_impl = self.params_impl[1:]
            self.params_impl = [Parameter("InstrumentingAgents* agents")] + self.params_impl

        self.agents = filter(lambda option: not "=" in option, self.options)

    def generate_header(self, header_lines):
        if "Inline=Custom" in self.options:
            return

        header_lines.append("%s %sImpl(%s);" % (
            self.return_type, self.name, ", ".join(map(Parameter.to_str_class, self.params_impl))))

        if "Inline=FastReturn" in self.options or "Inline=Forward" in self.options:
            fast_return = "\n    FAST_RETURN_IF_NO_FRONTENDS(%s);" % self.default_return_value
        else:
            fast_return = ""

        for param in self.params:
            if "FastReturn" in param.options:
                fast_return += "\n    if (!%s)\n        return %s;" % (param.name, self.default_return_value)

        if self.accepts_cookie:
            condition = "%s.isValid()" % self.params_impl[0].name
            template = template_inline
        elif "Inline=Forward" in self.options:
            condition = ""
            template = template_inline_forward
        else:
            condition = "InstrumentingAgents* agents = instrumentingAgentsFor(%s)" % self.params[0].name

            if self.returns_value:
                template = template_inline_returns_value
            else:
                template = template_inline

        header_lines.append(template.substitute(
            None,
            name=self.name,
            fast_return=fast_return,
            return_type=self.return_type,
            default_return_value=self.default_return_value,
            params_public=", ".join(map(Parameter.to_str_full, self.params)),
            params_impl=", ".join(map(Parameter.to_str_name, self.params_impl)),
            condition=condition))

    def generate_cpp(self, cpp_lines):
        if len(self.agents) == 0:
            return

        body_lines = map(self.generate_agent_call, self.agents)

        if self.returns_cookie:
            if "Timeline" in self.agents:
                timeline_agent_id = "timelineAgentId"
            else:
                timeline_agent_id = "0"
            body_lines.append("\n    return InspectorInstrumentationCookie(agents, %s);" % timeline_agent_id)
        elif self.returns_value:
            body_lines.append("\n    return %s;" % self.default_return_value)

        cpp_lines.append(template_outofline.substitute(
            None,
            return_type=self.return_type,
            name=self.name,
            params_impl=", ".join(map(Parameter.to_str_class_and_name, self.params_impl)),
            impl_lines="".join(body_lines)))

    def generate_agent_call(self, agent):
        agent_class, agent_getter = agent_getter_signature(agent)

        leading_param_name = self.params_impl[0].name
        if not self.accepts_cookie:
            agent_fetch = "%s->%s()" % (leading_param_name, agent_getter)
        elif agent == "Timeline":
            agent_fetch = "retrieveTimelineAgent(%s)" % leading_param_name
        else:
            agent_fetch = "%s.instrumentingAgents()->%s()" % (leading_param_name, agent_getter)

        if agent == "Timeline" and self.returns_cookie:
            template = template_agent_call_timeline_returns_cookie
        else:
            template = template_agent_call

        if not self.returns_value or self.returns_cookie:
            maybe_return = ""
        else:
            maybe_return = "return "

        return template.substitute(
            None,
            name=self.name,
            agent_class=agent_class,
            agent_fetch=agent_fetch,
            maybe_return=maybe_return,
            params_agent=", ".join(map(Parameter.to_str_value, self.params_impl)[1:]))


class Parameter:
    def __init__(self, source):
        self.options = []
        match, source = match_and_consume("\[(\w*)\]", source)
        if match:
            self.options.append(match.group(1))

        parts = map(str.strip, source.split("="))
        if len(parts) == 1:
            self.default_value = None
        else:
            self.default_value = parts[1]

        param_decl = parts[0]

        if re.match("(const|unsigned long) ", param_decl):
            min_type_tokens = 2
        else:
            min_type_tokens = 1

        if len(param_decl.split(" ")) > min_type_tokens:
            parts = param_decl.split(" ")
            self.type = " ".join(parts[:-1])
            self.name = parts[-1]
        else:
            self.type = param_decl
            self.name = generate_param_name(self.type)

        if re.match("PassRefPtr<", param_decl):
            self.value = "%s.get()" % self.name
        else:
            self.value = self.name


    def to_str_full(self):
        if self.default_value is None:
            return self.to_str_class_and_name()
        return "%s %s = %s" % (self.type, self.name, self.default_value)

    def to_str_class_and_name(self):
        return "%s %s" % (self.type, self.name)

    def to_str_class(self):
        return self.type

    def to_str_name(self):
        return self.name

    def to_str_value(self):
        return self.value


def generate_param_name(param_type):
    base_name = re.match("(const |PassRefPtr<)?(\w*)", param_type).group(2)
    return "param" + base_name


def agent_class_name(agent):
    custom_agent_names = ["PageDebugger", "PageRuntime", "WorkerRuntime"]
    if agent in custom_agent_names:
        return "%sAgent" % agent
    return "Inspector%sAgent" % agent


def agent_getter_signature(agent):
    agent_class = agent_class_name(agent)
    return agent_class, agent_class[0].lower() + agent_class[1:]


def include_header(name):
    return "#include \"%s.h\"" % name


def include_inspector_header(name):
    return include_header("core/inspector/" + name)


def generate_instrumenting_agents(used_agents):
    agents = list(used_agents)

    forward_list = []
    accessor_list = []
    member_list = []
    init_list = []
    trace_list = []
    reset_list = []

    for agent in agents:
        class_name, getter_name = agent_getter_signature(agent)
        member_name = "m_" + getter_name

        forward_list.append("class %s;" % class_name)
        accessor_list.append(template_instrumenting_agent_accessor.substitute(
            None,
            class_name=class_name,
            getter_name=getter_name,
            member_name=member_name))
        member_list.append("    RawPtrWillBeMember<%s> %s;" % (class_name, member_name))
        init_list.append("%s(nullptr)" % member_name)
        trace_list.append("visitor->trace(%s);" % member_name)
        reset_list.append("%s = nullptr;" % member_name)

    forward_list.sort()
    accessor_list.sort()
    member_list.sort()
    init_list.sort()
    trace_list.sort()
    reset_list.sort()

    header_lines = template_instrumenting_agents_h.substitute(
        None,
        forward_list="\n".join(forward_list),
        accessor_list="\n".join(accessor_list),
        member_list="\n".join(member_list))

    cpp_lines = template_instrumenting_agents_cpp.substitute(
        None,
        init_list="\n    , ".join(init_list),
        trace_list="\n    ".join(trace_list),
        reset_list="\n    ".join(reset_list))

    return header_lines, cpp_lines


def generate(input_path, output_dir):
    fin = open(input_path, "r")
    files = load_model_from_idl(fin.read())
    fin.close()

    cpp_includes = []
    cpp_lines = []
    used_agents = set()
    for f in files:
        cpp_includes.append(include_header(f.header_name))

        fout = open(output_dir + "/" + f.header_name + ".h", "w")
        fout.write(f.generate(cpp_lines, used_agents))
        fout.close()

    for agent in used_agents:
        cpp_includes.append(include_inspector_header(agent_class_name(agent)))
    cpp_includes.append(include_header("InstrumentingAgentsInl"))
    cpp_includes.sort()

    instrumenting_agents_header, instrumenting_agents_cpp = generate_instrumenting_agents(used_agents)

    fout = open(output_dir + "/" + "InstrumentingAgentsInl.h", "w")
    fout.write(instrumenting_agents_header)
    fout.close()

    fout = open(output_dir + "/InspectorInstrumentationImpl.cpp", "w")
    fout.write(template_cpp.substitute(None,
                                       includes="\n".join(cpp_includes),
                                       extra_definitions=instrumenting_agents_cpp,
                                       methods="\n".join(cpp_lines)))
    fout.close()


cmdline_parser = optparse.OptionParser()
cmdline_parser.add_option("--output_dir")

try:
    arg_options, arg_values = cmdline_parser.parse_args()
    if (len(arg_values) != 1):
        raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
    input_path = arg_values[0]
    output_dirpath = arg_options.output_dir
    if not output_dirpath:
        raise Exception("Output directory must be specified")
except Exception:
    # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
    exc = sys.exc_info()[1]
    sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
    sys.stderr.write("Usage: <script> --output_dir <output_dir> InspectorInstrumentation.idl\n")
    exit(1)

generate(input_path, output_dirpath)
