# The MIT License(MIT)
#
# Copyright(c) 2018 Hyperion Gray
#
# 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.

# This is a copy of https://github.com/HyperionGray/python-chrome-devtools-protocol/blob/master/generator/generate.py
# The license above is theirs and MUST be preserved.

# flake8: noqa

import builtins
from dataclasses import dataclass
from enum import Enum
import itertools
import json
import logging
import operator
import os
from pathlib import Path
import re
from textwrap import dedent, indent as tw_indent
import typing

import inflection  # type: ignore


log_level = getattr(logging, os.environ.get('LOG_LEVEL', 'warning').upper())
logging.basicConfig(level=log_level)
logger = logging.getLogger('generate')

SHARED_HEADER = '''# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.'''

INIT_HEADER = '''{}
'''.format(SHARED_HEADER)

MODULE_HEADER = '''{}
#
# CDP domain: {{}}{{}}
from __future__ import annotations
from .util import event_class, T_JSON_DICT
from dataclasses import dataclass
import enum
import typing
'''.format(SHARED_HEADER)

current_version = ''

UTIL_PY = """
import typing


T_JSON_DICT = typing.Dict[str, typing.Any]
_event_parsers = dict()


def event_class(method):
    ''' A decorator that registers a class as an event class. '''
    def decorate(cls):
        _event_parsers[method] = cls
        return cls
    return decorate


def parse_json_event(json: T_JSON_DICT) -> typing.Any:
    ''' Parse a JSON dictionary into a CDP event. '''
    return _event_parsers[json['method']].from_json(json['params'])
"""


def indent(s, n):
    ''' A shortcut for ``textwrap.indent`` that always uses spaces. '''
    return tw_indent(s, n * ' ')


BACKTICK_RE = re.compile(r'`([^`]+)`(\w+)?')


def escape_backticks(docstr):
    '''
    Escape backticks in a docstring by doubling them up.
    This is a little tricky because RST requires a non-letter character after
    the closing backticks, but some CDPs docs have things like "`AxNodeId`s".
    If we double the backticks in that string, then it won't be valid RST. The
    fix is to insert an apostrophe if an "s" trails the backticks.
    '''
    def replace_one(match):
        if match.group(2) == 's':
            return f"``{match.group(1)}``'s"
        if match.group(2):
            # This case (some trailer other than "s") doesn't currently exist
            # in the CDP definitions, but it's here just to be safe.
            return f'``{match.group(1)}`` {match.group(2)}'
        return f'``{match.group(1)}``'

    # Sometimes pipes are used where backticks should have been used.
    docstr = docstr.replace('|', '`')
    return BACKTICK_RE.sub(replace_one, docstr)


def inline_doc(description):
    ''' Generate an inline doc, e.g. ``#: This type is a ...`` '''
    if not description:
        return ''

    description = escape_backticks(description)
    lines = [f'#: {l}' for l in description.split('\n')]
    return '\n'.join(lines)


def docstring(description):
    ''' Generate a docstring from a description. '''
    if not description:
        return ''

    description = escape_backticks(description)
    return dedent("'''\n{}\n'''").format(description)


def is_builtin(name):
    ''' Return True if ``name`` would shadow a builtin. '''
    try:
        getattr(builtins, name)
        return True
    except AttributeError:
        return False


def snake_case(name):
    ''' Convert a camel case name to snake case. If the name would shadow a
    Python builtin, then append an underscore. '''
    name = inflection.underscore(name)
    if is_builtin(name):
        name += '_'
    return name


def ref_to_python(ref):
    '''
    Convert a CDP ``$ref`` to the name of a Python type.
    For a dotted ref, the part before the dot is snake cased.
    '''
    if '.' in ref:
        domain, subtype = ref.split('.')
        ref = f'{snake_case(domain)}.{subtype}'
    return f"{ref}"


class CdpPrimitiveType(Enum):
    ''' All of the CDP types that map directly to a Python type. '''
    boolean = 'bool'
    integer = 'int'
    number = 'float'
    object = 'dict'
    string = 'str'

    @classmethod
    def get_annotation(cls, cdp_type):
        ''' Return a type annotation for the CDP type. '''
        if cdp_type == 'any':
            return 'typing.Any'
        return cls[cdp_type].value

    @classmethod
    def get_constructor(cls, cdp_type, val):
        ''' Return the code to construct a value for a given CDP type. '''
        if cdp_type == 'any':
            return val
        cons = cls[cdp_type].value
        return f'{cons}({val})'


@dataclass
class CdpItems:
    ''' Represents the type of a repeated item. '''
    type: str
    ref: str

    @classmethod
    def from_json(cls, type):
        ''' Generate code to instantiate an item from a JSON object. '''
        return cls(type.get('type'), type.get('$ref'))


@dataclass
class CdpProperty:
    ''' A property belonging to a non-primitive CDP type. '''
    name: str
    description: typing.Optional[str]
    type: typing.Optional[str]
    ref: typing.Optional[str]
    enum: typing.List[str]
    items: typing.Optional[CdpItems]
    optional: bool
    experimental: bool
    deprecated: bool

    @property
    def py_name(self):
        ''' Get this property's Python name. '''
        return snake_case(self.name)

    @property
    def py_annotation(self):
        ''' This property's Python type annotation. '''
        if self.items:
            if self.items.ref:
                py_ref = ref_to_python(self.items.ref)
                ann = f"typing.List[{py_ref}]"
            else:
                ann = 'typing.List[{}]'.format(
                    CdpPrimitiveType.get_annotation(self.items.type))
        else:
            if self.ref:
                py_ref = ref_to_python(self.ref)
                ann = py_ref
            else:
                ann = CdpPrimitiveType.get_annotation(
                    typing.cast(str, self.type))
        if self.optional:
            ann = f'typing.Optional[{ann}]'
        return ann

    @classmethod
    def from_json(cls, property):
        ''' Instantiate a CDP property from a JSON object. '''
        return cls(
            property['name'],
            property.get('description'),
            property.get('type'),
            property.get('$ref'),
            property.get('enum'),
            CdpItems.from_json(property['items']) if 'items' in property else None,
            property.get('optional', False),
            property.get('experimental', False),
            property.get('deprecated', False),
        )

    def generate_decl(self):
        ''' Generate the code that declares this property. '''
        code = inline_doc(self.description)
        if code:
            code += '\n'
        code += f'{self.py_name}: {self.py_annotation}'
        if self.optional:
            code += ' = None'
        return code

    def generate_to_json(self, dict_, use_self=True):
        ''' Generate the code that exports this property to the specified JSON
        dict. '''
        self_ref = 'self.' if use_self else ''
        assign = f"{dict_}['{self.name}'] = "
        if self.items:
            if self.items.ref:
                assign += f"[i.to_json() for i in {self_ref}{self.py_name}]"
            else:
                assign += f"[i for i in {self_ref}{self.py_name}]"
        else:
            if self.ref:
                assign += f"{self_ref}{self.py_name}.to_json()"
            else:
                assign += f"{self_ref}{self.py_name}"
        if self.optional:
            code = dedent(f'''\
                if {self_ref}{self.py_name} is not None:
                    {assign}''')
        else:
            code = assign
        return code

    def generate_from_json(self, dict_):
        ''' Generate the code that creates an instance from a JSON dict named
        ``dict_``. '''
        if self.items:
            if self.items.ref:
                py_ref = ref_to_python(self.items.ref)
                expr = f"[{py_ref}.from_json(i) for i in {dict_}['{self.name}']]"
                expr
            else:
                cons = CdpPrimitiveType.get_constructor(self.items.type, 'i')
                expr = f"[{cons} for i in {dict_}['{self.name}']]"
        else:
            if self.ref:
                py_ref = ref_to_python(self.ref)
                expr = f"{py_ref}.from_json({dict_}['{self.name}'])"
            else:
                expr = CdpPrimitiveType.get_constructor(self.type,
                                                        f"{dict_}['{self.name}']")
        if self.optional:
            expr = f"{expr} if '{self.name}' in {dict_} else None"
        return expr


@dataclass
class CdpType:
    ''' A top-level CDP type. '''
    id: str
    description: typing.Optional[str]
    type: str
    items: typing.Optional[CdpItems]
    enum: typing.List[str]
    properties: typing.List[CdpProperty]

    @classmethod
    def from_json(cls, type_):
        ''' Instantiate a CDP type from a JSON object. '''
        return cls(
            type_['id'],
            type_.get('description'),
            type_['type'],
            CdpItems.from_json(type_['items']) if 'items' in type_ else None,
            type_.get('enum'),
            [CdpProperty.from_json(p) for p in type_.get('properties', [])],
        )

    def generate_code(self):
        ''' Generate Python code for this type. '''
        logger.debug('Generating type %s: %s', self.id, self.type)
        if self.enum:
            return self.generate_enum_code()
        if self.properties:
            return self.generate_class_code()
        return self.generate_primitive_code()

    def generate_primitive_code(self):
        ''' Generate code for a primitive type. '''
        if self.items:
            if self.items.ref:
                nested_type = ref_to_python(self.items.ref)
            else:
                nested_type = CdpPrimitiveType.get_annotation(self.items.type)
            py_type = f'typing.List[{nested_type}]'
            superclass = 'list'
        else:
            # A primitive type cannot have a ref, so there is no branch here.
            py_type = CdpPrimitiveType.get_annotation(self.type)
            superclass = py_type

        code = f'class {self.id}({superclass}):\n'
        doc = docstring(self.description)
        if doc:
            code += indent(doc, 4) + '\n'

        def_to_json = dedent(f'''\
            def to_json(self) -> {py_type}:
                return self''')
        code += indent(def_to_json, 4)

        def_from_json = dedent(f'''\
            @classmethod
            def from_json(cls, json: {py_type}) -> {self.id}:
                return cls(json)''')
        code += '\n\n' + indent(def_from_json, 4)

        def_repr = dedent(f'''\
            def __repr__(self):
                return '{self.id}({{}})'.format(super().__repr__())''')
        code += '\n\n' + indent(def_repr, 4)

        return code

    def generate_enum_code(self):
        '''
        Generate an "enum" type.
        Enums are handled by making a python class that contains only class
        members. Each class member is upper snaked case, e.g.
        ``MyTypeClass.MY_ENUM_VALUE`` and is assigned a string value from the
        CDP metadata.
        '''
        def_to_json = dedent('''\
            def to_json(self):
                return self.value''')

        def_from_json = dedent('''\
            @classmethod
            def from_json(cls, json):
                return cls(json)''')

        code = f'class {self.id}(enum.Enum):\n'
        doc = docstring(self.description)
        if doc:
            code += indent(doc, 4) + '\n'
        for enum_member in self.enum:
            snake_name = snake_case(enum_member).upper()
            enum_code = f'{snake_name} = "{enum_member}"\n'
            code += indent(enum_code, 4)
        code += '\n' + indent(def_to_json, 4)
        code += '\n\n' + indent(def_from_json, 4)

        return code

    def generate_class_code(self):
        '''
        Generate a class type.
        Top-level types that are defined as a CDP ``object`` are turned into Python
        dataclasses.
        '''
        # children = set()
        code = dedent(f'''\
            @dataclass
            class {self.id}:\n''')
        doc = docstring(self.description)
        if doc:
            code += indent(doc, 4) + '\n'

        # Emit property declarations. These are sorted so that optional
        # properties come after required properties, which is required to make
        # the dataclass constructor work.
        props = list(self.properties)
        props.sort(key=operator.attrgetter('optional'))
        code += '\n\n'.join(indent(p.generate_decl(), 4) for p in props)
        code += '\n\n'

        # Emit to_json() method. The properties are sorted in the same order as
        # above for readability.
        def_to_json = dedent('''\
            def to_json(self):
                json = dict()
        ''')
        assigns = (p.generate_to_json(dict_='json') for p in props)
        def_to_json += indent('\n'.join(assigns), 4)
        def_to_json += '\n'
        def_to_json += indent('return json', 4)
        code += indent(def_to_json, 4) + '\n\n'

        # Emit from_json() method. The properties are sorted in the same order
        # as above for readability.
        def_from_json = dedent('''\
            @classmethod
            def from_json(cls, json):
                return cls(
        ''')
        from_jsons = []
        for p in props:
            from_json = p.generate_from_json(dict_='json')
            from_jsons.append(f'{p.py_name}={from_json},')
        def_from_json += indent('\n'.join(from_jsons), 8)
        def_from_json += '\n'
        def_from_json += indent(')', 4)
        code += indent(def_from_json, 4)

        return code

    def get_refs(self):
        ''' Return all refs for this type. '''
        refs = set()
        if self.enum:
            # Enum types don't have refs.
            pass
        elif self.properties:
            # Enumerate refs for a class type.
            for prop in self.properties:
                if prop.items and prop.items.ref:
                    refs.add(prop.items.ref)
                elif prop.ref:
                    refs.add(prop.ref)
        else:
            # A primitive type can't have a direct ref, but it can have an items
            # which contains a ref.
            if self.items and self.items.ref:
                refs.add(self.items.ref)
        return refs


class CdpParameter(CdpProperty):
    ''' A parameter to a CDP command. '''

    def generate_code(self):
        ''' Generate the code for a parameter in a function call. '''
        if self.items:
            if self.items.ref:
                nested_type = ref_to_python(self.items.ref)
                py_type = f"typing.List[{nested_type}]"
            else:
                nested_type = CdpPrimitiveType.get_annotation(self.items.type)
                py_type = f'typing.List[{nested_type}]'
        else:
            if self.ref:
                py_type = f"{ref_to_python(self.ref)}"
            else:
                py_type = CdpPrimitiveType.get_annotation(
                    typing.cast(str, self.type))
        if self.optional:
            py_type = f'typing.Optional[{py_type}]'
        code = f"{self.py_name}: {py_type}"
        if self.optional:
            code += ' = None'
        return code

    def generate_decl(self):
        ''' Generate the declaration for this parameter. '''
        if self.description:
            code = inline_doc(self.description)
            code += '\n'
        else:
            code = ''
        code += f'{self.py_name}: {self.py_annotation}'
        return code

    def generate_doc(self):
        ''' Generate the docstring for this parameter. '''
        doc = f':param {self.py_name}:'

        if self.experimental:
            doc += ' **(EXPERIMENTAL)**'

        if self.optional:
            doc += ' *(Optional)*'

        if self.description:
            desc = self.description.replace('`', '``').replace('\n', ' ')
            doc += f' {desc}'
        return doc

    def generate_from_json(self, dict_):
        '''
        Generate the code to instantiate this parameter from a JSON dict.
        '''
        code = super().generate_from_json(dict_)
        return f'{self.py_name}={code}'


class CdpReturn(CdpProperty):
    ''' A return value from a CDP command. '''
    @property
    def py_annotation(self):
        ''' Return the Python type annotation for this return. '''
        if self.items:
            if self.items.ref:
                py_ref = ref_to_python(self.items.ref)
                ann = f"typing.List[{py_ref}]"
            else:
                py_type = CdpPrimitiveType.get_annotation(self.items.type)
                ann = f'typing.List[{py_type}]'
        else:
            if self.ref:
                py_ref = ref_to_python(self.ref)
                ann = f"{py_ref}"
            else:
                ann = CdpPrimitiveType.get_annotation(self.type)
        if self.optional:
            ann = f'typing.Optional[{ann}]'
        return ann

    def generate_doc(self):
        ''' Generate the docstring for this return. '''
        if self.description:
            doc = self.description.replace('\n', ' ')
            if self.optional:
                doc = f'*(Optional)* {doc}'
        else:
            doc = ''
        return doc

    def generate_return(self, dict_):
        ''' Generate code for returning this value. '''
        return super().generate_from_json(dict_)


@dataclass
class CdpCommand:
    ''' A CDP command. '''
    name: str
    description: str
    experimental: bool
    deprecated: bool
    parameters: typing.List[CdpParameter]
    returns: typing.List[CdpReturn]
    domain: str

    @property
    def py_name(self):
        ''' Get a Python name for this command. '''
        return snake_case(self.name)

    @classmethod
    def from_json(cls, command, domain) -> 'CdpCommand':
        ''' Instantiate a CDP command from a JSON object. '''
        parameters = command.get('parameters', [])
        returns = command.get('returns', [])

        return cls(
            command['name'],
            command.get('description'),
            command.get('experimental', False),
            command.get('deprecated', False),
            [typing.cast(CdpParameter, CdpParameter.from_json(p)) for p in parameters],
            [typing.cast(CdpReturn, CdpReturn.from_json(r)) for r in returns],
            domain,
        )

    def generate_code(self):
        ''' Generate code for a CDP command. '''
        global current_version
        # Generate the function header
        if len(self.returns) == 0:
            ret_type = 'None'
        elif len(self.returns) == 1:
            ret_type = self.returns[0].py_annotation
        else:
            nested_types = ', '.join(r.py_annotation for r in self.returns)
            ret_type = f'typing.Tuple[{nested_types}]'
        ret_type = f"typing.Generator[T_JSON_DICT,T_JSON_DICT,{ret_type}]"

        code = ''

        code += f'def {self.py_name}('
        ret = f') -> {ret_type}:\n'
        if self.parameters:
            params = [p.generate_code() for p in self.parameters]
            optional = False
            clean_params = []
            for para in params:
                if "= None" in para:
                    optional = True
                if optional and "= None" not in para:
                    para += ' = None'
                clean_params.append(para)
            code += '\n'
            code += indent(
                ',\n'.join(clean_params), 8)
            code += '\n'
            code += indent(ret, 4)
        else:
            code += ret

        # Generate the docstring
        doc = ''
        if self.description:
            doc = self.description
        if self.experimental:
            doc += '\n\n**EXPERIMENTAL**'
        if self.parameters and doc:
            doc += '\n\n'
        elif not self.parameters and self.returns:
            doc += '\n'
        doc += '\n'.join(p.generate_doc() for p in self.parameters)
        if len(self.returns) == 1:
            doc += '\n'
            ret_doc = self.returns[0].generate_doc()
            doc += f':returns: {ret_doc}'
        elif len(self.returns) > 1:
            doc += '\n'
            doc += ':returns: A tuple with the following items:\n\n'
            ret_docs = '\n'.join(f'{i}. **{r.name}** - {r.generate_doc()}' for i, r
                                 in enumerate(self.returns))
            doc += indent(ret_docs, 4)
        if doc:
            code += indent(docstring(doc), 4)

        # Generate the function body
        if self.parameters:
            code += '\n'
            code += indent('params: T_JSON_DICT = dict()', 4)
            code += '\n'
        assigns = (p.generate_to_json(dict_='params', use_self=False)
                   for p in self.parameters)
        code += indent('\n'.join(assigns), 4)
        code += '\n'
        code += indent('cmd_dict: T_JSON_DICT = {\n', 4)
        code += indent(f"'method': '{self.domain}.{self.name}',\n", 8)
        if self.parameters:
            code += indent("'params': params,\n", 8)
        code += indent('}\n', 4)
        code += indent('json = yield cmd_dict', 4)
        if len(self.returns) == 0:
            pass
        elif len(self.returns) == 1:
            ret = self.returns[0].generate_return(dict_='json')
            code += indent(f'\nreturn {ret}', 4)
        else:
            ret = '\nreturn (\n'
            expr = ',\n'.join(r.generate_return(dict_='json') for r in self.returns)
            ret += indent(expr, 4)
            ret += '\n)'
            code += indent(ret, 4)
        return code

    def get_refs(self):
        ''' Get all refs for this command. '''
        refs = set()
        for type_ in itertools.chain(self.parameters, self.returns):
            if type_.items and type_.items.ref:
                refs.add(type_.items.ref)
            elif type_.ref:
                refs.add(type_.ref)
        return refs


@dataclass
class CdpEvent:
    ''' A CDP event object. '''
    name: str
    description: typing.Optional[str]
    deprecated: bool
    experimental: bool
    parameters: typing.List[CdpParameter]
    domain: str

    @property
    def py_name(self):
        ''' Return the Python class name for this event. '''
        return inflection.camelize(self.name, uppercase_first_letter=True)

    @classmethod
    def from_json(cls, json: dict, domain: str):
        ''' Create a new CDP event instance from a JSON dict. '''
        return cls(
            json['name'],
            json.get('description'),
            json.get('deprecated', False),
            json.get('experimental', False),
            [typing.cast(CdpParameter, CdpParameter.from_json(p))
                for p in json.get('parameters', [])],
            domain
        )

    def generate_code(self):
        ''' Generate code for a CDP event. '''
        global current_version
        code = dedent(f'''\
            @event_class('{self.domain}.{self.name}')
            @dataclass
            class {self.py_name}:''')

        code += '\n'
        desc = ''
        if self.description or self.experimental:
            if self.experimental:
                desc += '**EXPERIMENTAL**\n\n'

            if self.description:
                desc += self.description

            code += indent(docstring(desc), 4)
            code += '\n'
        code += indent(
            '\n'.join(p.generate_decl() for p in self.parameters), 4)
        code += '\n\n'
        def_from_json = dedent(f'''\
            @classmethod
            def from_json(cls, json: T_JSON_DICT) -> {self.py_name}:
                return cls(
        ''')
        code += indent(def_from_json, 4)
        from_json = ',\n'.join(p.generate_from_json(dict_='json')
                               for p in self.parameters)
        code += indent(from_json, 12)
        code += '\n'
        code += indent(')', 8)
        return code

    def get_refs(self):
        ''' Get all refs for this event. '''
        refs = set()
        for param in self.parameters:
            if param.items and param.items.ref:
                refs.add(param.items.ref)
            elif param.ref:
                refs.add(param.ref)
        return refs


@dataclass
class CdpDomain:
    ''' A CDP domain contains metadata, types, commands, and events. '''
    domain: str
    description: typing.Optional[str]
    experimental: bool
    dependencies: typing.List[str]
    types: typing.List[CdpType]
    commands: typing.List[CdpCommand]
    events: typing.List[CdpEvent]

    @property
    def module(self):
        ''' The name of the Python module for this CDP domain. '''
        return snake_case(self.domain)

    @classmethod
    def from_json(cls, domain: dict):
        ''' Instantiate a CDP domain from a JSON object. '''
        types = domain.get('types', [])
        commands = domain.get('commands', [])
        events = domain.get('events', [])
        domain_name = domain['domain']

        return cls(
            domain_name,
            domain.get('description'),
            domain.get('experimental', False),
            domain.get('dependencies', []),
            [CdpType.from_json(type) for type in types],
            [CdpCommand.from_json(command, domain_name)
                for command in commands],
            [CdpEvent.from_json(event, domain_name) for event in events]
        )

    def generate_code(self):
        ''' Generate the Python module code for a given CDP domain. '''
        exp = ' (experimental)' if self.experimental else ''
        code = MODULE_HEADER.format(self.domain, exp)
        import_code = self.generate_imports()
        if import_code:
            code += import_code
            code += '\n\n'
        code += '\n'
        item_iter_t = typing.Union[CdpEvent, CdpCommand, CdpType]
        item_iter: typing.Iterator[item_iter_t] = itertools.chain(
            iter(self.types),
            iter(self.commands),
            iter(self.events),
        )
        code += '\n\n\n'.join(item.generate_code() for item in item_iter)
        code += '\n'
        return code

    def generate_imports(self):
        '''
        Determine which modules this module depends on and emit the code to
        import those modules.
        Notice that CDP defines a ``dependencies`` field for each domain, but
        these dependencies are a subset of the modules that we actually need to
        import to make our Python code work correctly and type safe. So we
        ignore the CDP's declared dependencies and compute them ourselves.
        '''
        refs = set()
        for type_ in self.types:
            refs |= type_.get_refs()
        for command in self.commands:
            refs |= command.get_refs()
        for event in self.events:
            refs |= event.get_refs()
        dependencies = set()
        for ref in refs:
            try:
                domain, _ = ref.split('.')
            except ValueError:
                continue
            if domain != self.domain:
                dependencies.add(snake_case(domain))
        code = '\n'.join(f'from . import {d}' for d in sorted(dependencies))

        return code

    def generate_sphinx(self):
        '''
        Generate a Sphinx document for this domain.
        '''
        docs = self.domain + '\n'
        docs += '=' * len(self.domain) + '\n\n'
        if self.description:
            docs += f'{self.description}\n\n'
        if self.experimental:
            docs += '*This CDP domain is experimental.*\n\n'
        docs += f'.. module:: cdp.{self.module}\n\n'
        docs += '* Types_\n* Commands_\n* Events_\n\n'

        docs += 'Types\n-----\n\n'
        if self.types:
            docs += dedent('''\
                Generally, you do not need to instantiate CDP types
                yourself. Instead, the API creates objects for you as return
                values from commands, and then you can use those objects as
                arguments to other commands.
            ''')
        else:
            docs += '*There are no types in this module.*\n'
        for type in self.types:
            docs += f'\n.. autoclass:: {type.id}\n'
            docs += '      :members:\n'
            docs += '      :undoc-members:\n'
            docs += '      :exclude-members: from_json, to_json\n'

        docs += '\nCommands\n--------\n\n'
        if self.commands:
            docs += dedent('''\
                Each command is a generator function. The return
                type ``Generator[x, y, z]`` indicates that the generator
                *yields* arguments of type ``x``, it must be resumed with
                an argument of type ``y``, and it returns type ``z``. In
                this library, types ``x`` and ``y`` are the same for all
                commands, and ``z`` is the return type you should pay attention
                to. For more information, see
                :ref:`Getting Started: Commands <getting-started-commands>`.
            ''')
        else:
            docs += '*There are no types in this module.*\n'
        for command in sorted(self.commands, key=operator.attrgetter('py_name')):
            docs += f'\n.. autofunction:: {command.py_name}\n'

        docs += '\nEvents\n------\n\n'
        if self.events:
            docs += dedent('''\
                Generally, you do not need to instantiate CDP events
                yourself. Instead, the API creates events for you and then
                you use the event\'s attributes.
            ''')
        else:
            docs += '*There are no events in this module.*\n'
        for event in self.events:
            docs += f'\n.. autoclass:: {event.py_name}\n'
            docs += '      :members:\n'
            docs += '      :undoc-members:\n'
            docs += '      :exclude-members: from_json, to_json\n'

        return docs


def parse(json_path, output_path):
    '''
    Parse JSON protocol description and return domain objects.
    :param Path json_path: path to a JSON CDP schema
    :param Path output_path: a directory path to create the modules in
    :returns: a list of CDP domain objects
    '''
    global current_version
    with open(json_path, encoding="utf-8") as json_file:
        schema = json.load(json_file)
    version = schema['version']
    assert (version['major'], version['minor']) == ('1', '3')
    current_version = f'{version["major"]}.{version["minor"]}'
    domains = []
    for domain in schema['domains']:
        domains.append(CdpDomain.from_json(domain))
    return domains


def generate_init(init_path, domains):
    '''
    Generate an ``__init__.py`` that exports the specified modules.
    :param Path init_path: a file path to create the init file in
    :param list[tuple] modules: a list of modules each represented as tuples
        of (name, list_of_exported_symbols)
    '''
    with open(init_path, "w", encoding="utf-8") as init_file:
        init_file.write(INIT_HEADER)
        for domain in domains:
            init_file.write(f'from . import {domain.module}\n')
        init_file.write('from . import util\n\n')


def generate_docs(docs_path, domains):
    '''
    Generate Sphinx documents for each domain.
    '''
    logger.info('Generating Sphinx documents')

    # Remove generated documents
    for subpath in docs_path.iterdir():
        subpath.unlink()

    # Generate document for each domain
    for domain in domains:
        doc = docs_path / f'{domain.module}.rst'
        with doc.open('w') as f:
            f.write(domain.generate_sphinx())


def main(browser_protocol_path, js_protocol_path, output_path):
    ''' Main entry point. '''
    output_path = Path(output_path).resolve()
    json_paths = [
        browser_protocol_path,
        js_protocol_path,
    ]

    # Generate util.py
    util_path = output_path / "util.py"
    with util_path.open('w') as util_file:
        util_file.write(UTIL_PY)

    # Remove generated code
    for subpath in output_path.iterdir():
        if subpath.is_file() and subpath.name not in ('py.typed', 'util.py'):
            subpath.unlink()

    # Parse domains
    domains = []
    for json_path in json_paths:
        logger.info('Parsing JSON file %s', json_path)
        domains.extend(parse(json_path, output_path))
    domains.sort(key=operator.attrgetter('domain'))

    # Patch up CDP errors. It's easier to patch that here than it is to modify
    # the generator code.
    # 1. DOM includes an erroneous $ref that refers to itself.
    # 2. Page includes an event with an extraneous backtick in the description.
    for domain in domains:
        if domain.domain == 'DOM':
            for cmd in domain.commands:
                if cmd.name == 'resolveNode':
                    # Patch 1
                    cmd.parameters[1].ref = 'BackendNodeId'
        elif domain.domain == 'Page':
            for event in domain.events:
                if event.name == 'screencastVisibilityChanged':
                    # Patch 2
                    event.description = event.description.replace('`', '')

    for domain in domains:
        logger.info('Generating module: %s → %s.py', domain.domain,
                    domain.module)
        module_path = output_path / f'{domain.module}.py'
        with module_path.open('w') as module_file:
            module_file.write(domain.generate_code())

    init_path = output_path / '__init__.py'
    generate_init(init_path, domains)

    # Not generating the docs as we don't want people to directly
    # Use the CDP APIs
    # docs_path = here.parent / 'docs' / 'api'
    # generate_docs(docs_path, domains)

    py_typed_path = output_path / 'py.typed'
    py_typed_path.touch()


if __name__ == '__main__':
    import sys
    assert sys.version_info >= (3, 7), "To generate the CDP code requires python 3.7 or later"
    args = sys.argv[1:]
    main(*args)
