#!/usr/bin/env python
# Copyright (c) 2011 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 os
import os.path as path
import re
import sys
try:
    import json
except ImportError:
    import simplejson as json

sys.path.append(path.dirname(path.abspath(__file__)))

from devtools_paths import third_party_path

sys.path.append(path.join(third_party_path(), 'inspector_protocol'))
import pdl  # pylint: disable=F0401

type_traits = {
    "any": "*",
    "string": "string",
    "binary": "string",
    "integer": "number",
    "number": "number",
    "boolean": "boolean",
    "array": "!Array<*>",
    "object": "!Object",
}

ref_types = {}


def full_qualified_type_id(domain_name, type_id):
    if type_id.find(".") == -1:
        return "%s.%s" % (domain_name, type_id)
    return type_id


def fix_camel_case(name):
    prefix = ""
    if name[0] == "-":
        prefix = "Negative"
        name = name[1:]
    refined = re.sub(r'-(\w)', lambda pat: pat.group(1).upper(), name)
    refined = to_title_case(refined)
    return prefix + re.sub(r'(?i)HTML|XML|WML|API', lambda pat: pat.group(0).upper(), refined)


def to_title_case(name):
    return name[:1].upper() + name[1:]


def generate_enum(name, json):
    enum_members = []
    for member in json["enum"]:
        enum_members.append("    %s: \"%s\"" % (fix_camel_case(member), member))
    return "\n/** @enum {string} */\n%s = {\n%s\n};\n" % (name, (",\n".join(enum_members)))


def param_type(domain_name, param, command=None):
    if "enum" in param and command:
        return "Protocol.%s.%sRequest%s" % (domain_name,
                                            to_title_case(command["name"]),
                                            to_title_case(param_name(param)))
    if "type" in param:
        if param["type"] == "array":
            items = param["items"]
            return "!Array<%s>" % param_type(domain_name, items)
        else:
            return "Protocol.%s" % param["type"]
    if "$ref" in param:
        type_id = full_qualified_type_id(domain_name, param["$ref"])
        if type_id in ref_types:
            return ref_types[type_id]
        else:
            print "Type not found: " + type_id
            return "!! Type not found: " + type_id


def param_name(param):
    name = param["name"]
    return name if name != "arguments" else "_arguments"


def load_schema(file, domains):
    input_file = open(file, "r")
    parsed_json = pdl.loads(input_file.read(), file)
    input_file.close()
    domains.extend(parsed_json["domains"])


def generate_protocol_externs(output_path, file1, file2):
    domains = []
    load_schema(file1, domains)
    load_schema(file2, domains)
    output_file = open(output_path, "w")
    output_file.write("var ProtocolProxyApi = {};\n")

    # Add basic types from protocol to closure
    for protocolName, closureName in type_traits.items():
        output_file.write("/** @typedef {%s} */\n" % closureName)
        output_file.write("Protocol.%s;\n" % protocolName)

    # Used for enforcing whether a dispatcher uses an object or not
    output_file.write("/** @typedef {boolean} */\n")
    output_file.write("Protocol.UsesObjectNotation;\n")

    for domain in domains:
        domain_name = domain["domain"]
        if "types" in domain:
            for type in domain["types"]:
                type_id = full_qualified_type_id(domain_name, type["id"])
                ref_types[type_id] = "Protocol.%s.%s" % (domain_name, type["id"])

    for domain in domains:
        domain_name = domain["domain"]

        output_file.write("Protocol.%s = {};\n" % domain_name)
        output_file.write("\n\n/**\n * @constructor\n*/\n")
        output_file.write("Protocol.%sAgent = function(){};\n" % domain_name)
        output_file.write("\n\n/**\n * @constructor\n*/\n")
        output_file.write("ProtocolProxyApi.%sApi = Protocol.%sAgent;\n" % (domain_name, domain_name))

        if "commands" in domain:
            for command in domain["commands"]:
                params = []
                in_param_to_type = {}
                out_param_to_type = {}
                has_return_value = "returns" in command

                if "parameters" in command:
                    for param in command["parameters"]:
                        if "enum" in param:
                            enum_name = param_type(domain_name, param, command)
                            output_file.write(generate_enum(enum_name, param))

                output_file.write("\n/**\n")

                if "parameters" in command:
                    # Only declare trailing optional parameters as optional in
                    # JSDoc annotations.
                    trailing_optional = set()
                    for in_param in reversed(command["parameters"]):
                        if "optional" not in in_param:
                            break
                        trailing_optional.add(param_name(in_param))

                    for in_param in command["parameters"]:
                        in_param_name = param_name(in_param)
                        real_in_param_name = "opt_" + in_param_name if in_param_name in trailing_optional else in_param_name
                        params.append(real_in_param_name)
                        if "optional" in in_param:
                            in_param_to_type[
                                in_param_name] = "(%s|undefined)" % param_type(
                                    domain_name, in_param, command)
                            annotation_suffix = "=" if in_param_name in trailing_optional else "|undefined"
                        else:
                            in_param_to_type[in_param_name] = param_type(
                                domain_name, in_param, command)
                            annotation_suffix = ""
                        output_file.write(
                            " * @param {%s%s} %s\n" %
                            (param_type(domain_name, in_param, command),
                             annotation_suffix, real_in_param_name))
                returns = []
                returns.append("?Protocol.Error")
                if ("error" in command):
                    returns.append("%s=" % param_type(domain_name, command["error"]))
                if (has_return_value):
                    for out_param in command["returns"]:
                        out_param_type = param_type(domain_name, out_param)
                        out_param_to_type[out_param["name"]] = out_param_type
                        if ("optional" in out_param):
                            returns.append("%s=" % out_param_type)
                        else:
                            returns.append("%s" % out_param_type)

                if has_return_value and len(command["returns"]) > 0:
                    out_param_type = param_type(domain_name, command["returns"][0])
                    if re.match(r"^[!?]", out_param_type[:1]):
                        out_param_type = out_param_type[1:]
                    out_param_type = "?%s" % out_param_type
                else:
                    out_param_type = "undefined"
                output_file.write(" * @return {!Promise<%s>}\n" % out_param_type)

                output_file.write(" */\n")
                output_file.write(
                    "Protocol.%sAgent.prototype.%s = function(%s) {};\n" % (domain_name, command["name"], ", ".join(params)))

                request_object_properties = []
                request_type = "Protocol.%s.%sRequest" % (
                    domain_name, to_title_case(command["name"]))
                for param in in_param_to_type:
                    request_object_properties.append("%s: %s" % (param, in_param_to_type[param]))
                if request_object_properties:
                    output_file.write("/** @typedef {!{%s}} */\n" % (", ".join(request_object_properties)))
                else:
                    output_file.write("/** @typedef {Object|undefined} */\n")
                output_file.write("%s;\n" % request_type)

                response_object_properties = []
                response_type = "Protocol.%s.%sResponse" % (
                    domain_name, to_title_case(command["name"]))
                for param in out_param_to_type:
                    response_object_properties.append("%s: %s" % (param, out_param_to_type[param]))
                if response_object_properties:
                    output_file.write("/** @typedef {!{%s}} */\n" % (", ".join(response_object_properties)))
                else:
                    output_file.write("/** @typedef {Object|undefined} */\n")
                output_file.write("%s;\n" % response_type)

                output_file.write("/**\n")
                output_file.write(" * @param {!%s=} obj\n" % request_type)
                output_file.write(" * @return {!Promise<!%s>}" % response_type)
                output_file.write(" */\n")
                output_file.write("Protocol.%sAgent.prototype.invoke_%s = function(obj) {};\n" % (domain_name, command["name"]))

        if "types" in domain:
            for type in domain["types"]:
                if type["type"] == "object":
                    typedef_args = []
                    if "properties" in type:
                        for property in type["properties"]:
                            suffix = ""
                            if ("optional" in property):
                                suffix = "|undefined"
                            if "enum" in property:
                                enum_name = "Protocol.%s.%s%s" % (domain_name, type["id"], to_title_case(property["name"]))
                                output_file.write(generate_enum(enum_name, property))
                                typedef_args.append("%s:(%s%s)" % (property["name"], enum_name, suffix))
                            else:
                                typedef_args.append("%s:(%s%s)" % (property["name"], param_type(domain_name, property), suffix))
                    if (typedef_args):
                        output_file.write(
                            "\n/** @typedef {!{%s}} */\nProtocol.%s.%s;\n" % (", ".join(typedef_args), domain_name, type["id"]))
                    else:
                        output_file.write("\n/** @typedef {!Object} */\nProtocol.%s.%s;\n" % (domain_name, type["id"]))
                elif type["type"] == "string" and "enum" in type:
                    output_file.write(generate_enum("Protocol.%s.%s" % (domain_name, type["id"]), type))
                elif type["type"] == "array":
                    output_file.write("\n/** @typedef {!Array<!%s>} */\nProtocol.%s.%s;\n" % (param_type(
                        domain_name, type["items"]), domain_name, type["id"]))
                else:
                    output_file.write(
                        "\n/** @typedef {%s} */\nProtocol.%s.%s;\n" % (type_traits[type["type"]], domain_name, type["id"]))

        if domain_name in ["Runtime", "Debugger", "HeapProfiler"]:
            output_file.write("/** @constructor */\n")
        else:
            output_file.write("/** @interface */\n")
        output_file.write("Protocol.%sDispatcher = function() {};\n" % domain_name)
        output_file.write("/** @interface */\n")
        output_file.write("ProtocolProxyApi.%sDispatcher = function() {};\n" %
                          domain_name)
        # Include the workaround for https://github.com/microsoft/TypeScript/issues/38640
        output_file.write(
            "var ProtocolProxyApiWorkaround_%sDispatcher = ProtocolProxyApi.%sDispatcher;\n"
            % (domain_name, domain_name))
        if "events" in domain:
            for event in domain["events"]:
                params = []
                if ("parameters" in event):
                    output_file.write("/**\n")
                    for param in event["parameters"]:
                        if ("optional" in param):
                            params.append("opt_%s" % param["name"])
                            output_file.write(" * @param {%s=} opt_%s\n" % (param_type(domain_name, param), param["name"]))
                        else:
                            params.append(param["name"])
                            output_file.write(" * @param {%s} %s\n" % (param_type(domain_name, param), param["name"]))
                    output_file.write(" */\n")
                output_file.write(
                    "Protocol.%sDispatcher.prototype.%s = function(%s) {};\n" % (domain_name, event["name"], ", ".join(params)))

                # Generate a Event typedef that is used in dispatchers
                if ("parameters" in event):
                    output_file.write("/**\n")
                    output_file.write("* @typedef {{")
                    for param in event["parameters"]:
                        full_param_type = param_type(domain_name, param)
                        if ("optional" in param):
                            full_param_type = "(%s|undefined)" % full_param_type
                        output_file.write("%s: %s," %
                                          (param["name"], full_param_type))
                    output_file.write("}} */\n")
                else:
                    output_file.write("/**\n")
                    output_file.write("* @typedef {Object}")
                    output_file.write("*/\n")
                output_file.write("Protocol.%s.%sEvent;\n" %
                                  (domain_name, to_title_case(event["name"])))

                # Add the interface method to the dispatcher type, which takes 1 event as argument
                output_file.write("/**\n")
                output_file.write("@param {!Protocol.%s.%sEvent} request\n" %
                                  (domain_name, to_title_case(event["name"])))
                output_file.write("*/\n")
                output_file.write(
                    "ProtocolProxyApi.%sDispatcher.prototype.%s = function(request) {};\n"
                    % (domain_name, event["name"]))

    for domain in domains:
        domain_name = domain["domain"]
        uppercase_length = 0
        while uppercase_length < len(domain_name) and domain_name[uppercase_length].isupper():
            uppercase_length += 1

        output_file.write("/** @return {!Protocol.%sAgent}*/\n" % domain_name)
        output_file.write("ProtocolClient.TargetBase.prototype.%s = function(){};\n" %
                          (domain_name[:uppercase_length].lower() + domain_name[uppercase_length:] + "Agent"))

        output_file.write(
            "/**\n * @param {!Protocol.%sDispatcher|!ProtocolProxyApi.%sDispatcher} dispatcher\n */\n"
            % (domain_name, domain_name))
        output_file.write("ProtocolClient.TargetBase.prototype.register%sDispatcher = function(dispatcher) {}\n" % domain_name)

    output_file.close()


if __name__ == "__main__":
    import sys
    import os.path
    program_name = os.path.basename(__file__)
    if len(sys.argv) < 5 or sys.argv[1] != "-o":
        sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE_1 INPUT_FILE_2\n" % program_name)
        exit(1)
    output_path = sys.argv[2]
    input_path_1 = sys.argv[3]
    input_path_2 = sys.argv[4]
    generate_protocol_externs(output_path, input_path_1, input_path_2)
