import keyword

from pycharm_generator_utils.util_methods import *
from pycharm_generator_utils.constants import *


class emptylistdict(dict):
    """defaultdict not available before 2.5; simplest reimplementation using [] as default"""

    def __getitem__(self, item):
        if item in self:
            return dict.__getitem__(self, item)
        else:
            it = []
            self.__setitem__(item, it)
            return it

class Buf(object):
    """Buffers data in a list, can write to a file. Indentation is provided externally."""

    def __init__(self, indenter):
        self.data = []
        self.indenter = indenter

    def put(self, data):
        if data:
            self.data.append(ensureUnicode(data))

    def out(self, indent, *what):
        """Output the arguments, indenting as needed, and adding an eol"""
        self.put(self.indenter.indent(indent))
        for item in what:
            self.put(item)
        self.put("\n")

    def flush_bytes(self, outfile):
        for data in self.data:
            outfile.write(data.encode(OUT_ENCODING, "replace"))

    def flush_str(self, outfile):
        for data in self.data:
            outfile.write(data)

    if version[0] < 3:
        flush = flush_bytes
    else:
        flush = flush_str

    def isEmpty(self):
        return len(self.data) == 0


class ClassBuf(Buf):
    def __init__(self, name, indenter):
        super(ClassBuf, self).__init__(indenter)
        self.name = name

#noinspection PyUnresolvedReferences,PyBroadException
class ModuleRedeclarator(object):
    def __init__(self, module, outfile, mod_filename, indent_size=4, doing_builtins=False):
        """
        Create new instance.
        @param module module to restore.
        @param outfile output file, must be open and writable.
        @param mod_filename filename of binary module (the .dll or .so)
        @param indent_size amount of space characters per indent
        """
        self.module = module
        self.outfile = outfile # where we finally write
        self.mod_filename = mod_filename
        # we write things into buffers out-of-order
        self.header_buf = Buf(self)
        self.imports_buf = Buf(self)
        self.functions_buf = Buf(self)
        self.classes_buf = Buf(self)
        self.classes_buffs = list()
        self.footer_buf = Buf(self)
        self.indent_size = indent_size
        self._indent_step = " " * self.indent_size
        self.split_modules = False
        #
        self.imported_modules = {"": the_builtins} # explicit module imports: {"name": module}
        self.hidden_imports = {} # {'real_mod_name': 'alias'}; we alias names with "__" since we don't want them exported
        # ^ used for things that we don't re-export but need to import, e.g. certain base classes in gnome.
        self._defined = {} # stores True for every name defined so far, to break circular refs in values
        self.doing_builtins = doing_builtins
        self.ret_type_cache = {}
        self.used_imports = emptylistdict() # qual_mod_name -> [imported_names,..]: actually used imported names

    def _initializeQApp4(self):
        try:  # QtGui should be imported _before_ QtCore package.
            # This is done for the QWidget references from QtCore (such as QSignalMapper). Known bug in PyQt 4.7+
            # Causes "TypeError: C++ type 'QWidget*' is not supported as a native Qt signal type"
            import PyQt4.QtGui
        except ImportError:
            pass

        # manually instantiate and keep reference to singleton QCoreApplication (we don't want it to be deleted during the introspection)
        # use QCoreApplication instead of QApplication to avoid blinking app in Dock on Mac OS
        try:
            from PyQt4.QtCore import QCoreApplication
            self.app = QCoreApplication([])
            return
        except ImportError:
            pass

    def _initializeQApp5(self):
        try:
            from PyQt5.QtCore import QCoreApplication
            self.app = QCoreApplication([])
            return
        except ImportError:
            pass

    def indent(self, level):
        """Return indentation whitespace for given level."""
        return self._indent_step * level

    def flush(self):
        init = None
        try:
            if self.split_modules:
                mod_path = module_to_package_name(self.outfile)

                fname = build_output_name(mod_path, "__init__")
                init = fopen(fname, "w")
                for buf in (self.header_buf, self.imports_buf, self.functions_buf, self.classes_buf):
                    buf.flush(init)

                data = ""
                for buf in self.classes_buffs:
                    fname = build_output_name(mod_path, buf.name)
                    dummy = fopen(fname, "w")
                    self.header_buf.flush(dummy)
                    self.imports_buf.flush(dummy)
                    buf.flush(dummy)
                    data += self.create_local_import(buf.name)
                    dummy.close()

                init.write(data)
                self.footer_buf.flush(init)
            else:
                init = fopen(self.outfile, "w")
                for buf in (self.header_buf, self.imports_buf, self.functions_buf, self.classes_buf):
                    buf.flush(init)

                for buf in self.classes_buffs:
                    buf.flush(init)

                self.footer_buf.flush(init)

        finally:
            if init is not None and not init.closed:
                init.close()

    # Some builtin classes effectively change __init__ signature without overriding it.
    # This callable serves as a placeholder to be replaced via REDEFINED_BUILTIN_SIGS
    def fake_builtin_init(self):
        pass # just a callable, sig doesn't matter

    fake_builtin_init.__doc__ = object.__init__.__doc__ # this forces class's doc to be used instead

    def create_local_import(self, name):
        if len(name.split(".")) > 1: return ""
        data = "from "
        if version[0] >= 3:
            data += "."
        data += name + " import " + name + "\n"
        return data

    def find_imported_name(self, item):
        """
        Finds out how the item is represented in imported modules.
        @param item what to check
        @return qualified name (like "sys.stdin") or None
        """
        # TODO: return a pair, not a glued string
        if not isinstance(item, SIMPLEST_TYPES):
            for mname in self.imported_modules:
                m = self.imported_modules[mname]
                for inner_name in m.__dict__:
                    suspect = getattr(m, inner_name)
                    if suspect is item:
                        if mname:
                            mname += "."
                        elif self.module is the_builtins: # don't short-circuit builtins
                            return None
                        return mname + inner_name
        return None

    _initializers = (
        (dict, "{}"),
        (tuple, "()"),
        (list, "[]"),
    )

    def invent_initializer(self, a_type):
        """
        Returns an innocuous initializer expression for a_type, or "None"
        """
        for initializer_type, r in self._initializers:
            if initializer_type == a_type:
                return r
                # NOTE: here we could handle things like defaultdict, sets, etc if we wanted
        return "None"


    def fmt_value(self, out, p_value, indent, prefix="", postfix="", as_name=None, seen_values=None):
        """
        Formats and outputs value (it occupies an entire line or several lines).
        @param out function that does output (a Buf.out)
        @param p_value the value.
        @param indent indent level.
        @param prefix text to print before the value
        @param postfix text to print after the value
        @param as_name hints which name are we trying to print; helps with circular refs.
        @param seen_values a list of keys we've seen if we're processing a dict
        """
        SELF_VALUE = "<value is a self-reference, replaced by this string>"
        ERR_VALUE = "<failed to retrieve the value>"
        if isinstance(p_value, SIMPLEST_TYPES):
            out(indent, prefix, reliable_repr(p_value), postfix)
        else:
            if sys.platform == "cli":
                imported_name = None
            else:
                imported_name = self.find_imported_name(p_value)
            if imported_name:
                out(indent, prefix, imported_name, postfix)
                # TODO: kind of self.used_imports[imported_name].append(p_value) but split imported_name
                # else we could potentially return smth we did not otherwise import. but not likely.
            else:
                if isinstance(p_value, (list, tuple)):
                    if not seen_values:
                        seen_values = [p_value]
                    if len(p_value) == 0:
                        out(indent, prefix, repr(p_value), postfix)
                    else:
                        if isinstance(p_value, list):
                            lpar, rpar = "[", "]"
                        else:
                            lpar, rpar = "(", ")"
                        out(indent, prefix, lpar)
                        for value in p_value:
                            if value in seen_values:
                                value = SELF_VALUE
                            elif not isinstance(value, SIMPLEST_TYPES):
                                seen_values.append(value)
                            self.fmt_value(out, value, indent + 1, postfix=",", seen_values=seen_values)
                        out(indent, rpar, postfix)
                elif isinstance(p_value, dict):
                    if len(p_value) == 0:
                        out(indent, prefix, repr(p_value), postfix)
                    else:
                        if not seen_values:
                            seen_values = [p_value]
                        out(indent, prefix, "{")
                        keys = list(p_value.keys())
                        try:
                            keys.sort()
                        except TypeError:
                            pass # unsortable keys happen, e,g, in py3k _ctypes
                        for k in keys:
                            value = p_value[k]

                            try:
                                is_seen = value in seen_values
                            except:
                                is_seen = False
                                value = ERR_VALUE

                            if is_seen:
                                value = SELF_VALUE
                            elif not isinstance(value, SIMPLEST_TYPES):
                                seen_values.append(value)
                            if isinstance(k, SIMPLEST_TYPES):
                                self.fmt_value(out, value, indent + 1, prefix=repr(k) + ": ", postfix=",",
                                               seen_values=seen_values)
                            else:
                                # both key and value need fancy formatting
                                self.fmt_value(out, k, indent + 1, postfix=": ", seen_values=seen_values)
                                self.fmt_value(out, value, indent + 2, seen_values=seen_values)
                                out(indent + 1, ",")
                        out(indent, "}", postfix)
                else: # something else, maybe representable
                    # look up this value in the module.
                    if sys.platform == "cli":
                        out(indent, prefix, "None", postfix)
                        return
                    found_name = ""
                    for inner_name in self.module.__dict__:
                        if self.module.__dict__[inner_name] is p_value:
                            found_name = inner_name
                            break
                    if self._defined.get(found_name, False):
                        out(indent, prefix, found_name, postfix)
                    else:
                        # a forward / circular declaration happens
                        notice = ""
                        try:
                            representation = repr(p_value)
                        except Exception:
                            import traceback
                            traceback.print_exc(file=sys.stderr)
                            return
                        real_value = cleanup(representation)
                        if found_name:
                            if found_name == as_name:
                                notice = " # (!) real value is %r" % real_value
                                real_value = "None"
                            else:
                                notice = " # (!) forward: %s, real value is %r" % (found_name, real_value)
                        if SANE_REPR_RE.match(real_value):
                            out(indent, prefix, real_value, postfix, notice)
                        else:
                            if not found_name:
                                notice = " # (!) real value is %r" % real_value
                            out(indent, prefix, "None", postfix, notice)

    def get_ret_type(self, attr):
        """
        Returns a return type string as given by T_RETURN in tokens, or None
        """
        if attr:
            ret_type = RET_TYPE.get(attr, None)
            if ret_type:
                return ret_type
            thing = getattr(self.module, attr, None)
            if thing:
                if not isinstance(thing, type) and is_callable(thing): # a function
                    return None # TODO: maybe divinate a return type; see pygame.mixer.Channel
                return attr
                # adds no noticeable slowdown, I did measure. dch.
            for im_name, im_module in self.imported_modules.items():
                cache_key = (im_name, attr)
                cached = self.ret_type_cache.get(cache_key, None)
                if cached:
                    return cached
                ret_type = getattr(im_module, attr, None)
                if ret_type:
                    if isinstance(ret_type, type):
                        # detect a constructor
                        constr_args = detect_constructor(ret_type)
                        if constr_args is None:
                            constr_args = "*(), **{}" # a silly catch-all constructor
                        reference = "%s(%s)" % (attr, constr_args)
                    elif is_callable(ret_type): # a function, classes are ruled out above
                        return None
                    else:
                        reference = attr
                    if im_name:
                        result = "%s.%s" % (im_name, reference)
                    else: # built-in
                        result = reference
                    self.ret_type_cache[cache_key] = result
                    return result
                    # TODO: handle things like "[a, b,..] and (foo,..)"
        return None


    SIG_DOC_NOTE = "restored from __doc__"
    SIG_DOC_UNRELIABLY = "NOTE: unreliably restored from __doc__ "

    def restore_by_docstring(self, signature_string, class_name, deco=None, ret_hint=None):
        """
        @param signature_string: parameter list extracted from the doc string.
        @param class_name: name of the containing class, or None
        @param deco: decorator to use
        @param ret_hint: return type hint, if available
        @return (reconstructed_spec, return_type, note) or (None, _, _) if failed.
        """
        action("restoring func %r of class %r", signature_string, class_name)
        # parse
        parsing_failed = False
        ret_type = None
        try:
            # strict parsing
            tokens = paramSeqAndRest.parseString(signature_string, True)
            ret_name = None
            if tokens:
                ret_t = tokens[-1]
                if ret_t[0] is T_RETURN:
                    ret_name = ret_t[1]
            ret_type = self.get_ret_type(ret_name) or self.get_ret_type(ret_hint)
        except ParseException:
            # it did not parse completely; scavenge what we can
            parsing_failed = True
            tokens = []
            try:
                # most unrestrictive parsing
                tokens = paramSeq.parseString(signature_string, False)
            except ParseException:
                pass
                #
        seq = transform_seq(tokens)

        # add safe defaults for unparsed
        if parsing_failed:
            doc_node = self.SIG_DOC_UNRELIABLY
            starred = None
            double_starred = None
            for one in seq:
                if type(one) is str:
                    if one.startswith("**"):
                        double_starred = one
                    elif one.startswith("*"):
                        starred = one
            if not starred:
                seq.append("*args")
            if not double_starred:
                seq.append("**kwargs")
        else:
            doc_node = self.SIG_DOC_NOTE

        # add 'self' if needed YYY
        if class_name and (not seq or seq[0] != 'self'):
            first_param = propose_first_param(deco)
            if first_param:
                seq.insert(0, first_param)
        seq = make_names_unique(seq)
        return (seq, ret_type, doc_node)

    def parse_func_doc(self, func_doc, func_id, func_name, class_name, deco=None, sip_generated=False):
        """
        @param func_doc: __doc__ of the function.
        @param func_id: name to look for as identifier of the function in docstring
        @param func_name: name of the function.
        @param class_name: name of the containing class, or None
        @param deco: decorator to use
        @return (reconstructed_spec, return_literal, note) or (None, _, _) if failed.
        """
        if sip_generated:
            overloads = []
            for part in func_doc.split('\n'):
                signature = func_id + '('
                i = part.find(signature)
                if i >= 0:
                    overloads.append(part[i + len(signature):])
            if len(overloads) > 1:
                docstring_results = [self.restore_by_docstring(overload, class_name, deco) for overload in overloads]
                ret_types = []
                for result in docstring_results:
                    rt = result[1]
                    if rt and rt not in ret_types:
                        ret_types.append(rt)
                if ret_types:
                    ret_literal = " or ".join(ret_types)
                else:
                    ret_literal = None
                param_lists = [result[0] for result in docstring_results]
                spec = build_signature(func_name, restore_parameters_for_overloads(param_lists))
                return (spec, ret_literal, "restored from __doc__ with multiple overloads")

        # find the first thing to look like a definition
        prefix_re = re.compile("\s*(?:(\w+)[ \\t]+)?" + func_id + "\s*\(") # "foo(..." or "int foo(..."
        match = prefix_re.search(func_doc) # Note: this and previous line may consume up to 35% of time
        # parse the part that looks right
        if match:
            ret_hint = match.group(1)
            params, ret_literal, doc_note = self.restore_by_docstring(func_doc[match.end():], class_name, deco, ret_hint)
            spec = func_name + flatten(params)
            return (spec, ret_literal, doc_note)
        else:
            return (None, None, None)


    def is_predefined_builtin(self, module_name, class_name, func_name):
        return self.doing_builtins and module_name == BUILTIN_MOD_NAME and (
            class_name, func_name) in PREDEFINED_BUILTIN_SIGS


    def redo_function(self, out, p_func, p_name, indent, p_class=None, p_modname=None, classname=None, seen=None):
        """
        Restore function argument list as best we can.
        @param out output function of a Buf
        @param p_func function or method object
        @param p_name function name as known to owner
        @param indent indentation level
        @param p_class the class that contains this function as a method
        @param p_modname module name
        @param seen {id(func): name} map of functions already seen in the same namespace;
               id() because *some* functions are unhashable (eg _elementtree.Comment in py2.7)
        """
        action("redoing func %r of class %r", p_name, p_class)
        if seen is not None:
            other_func = seen.get(id(p_func), None)
            if other_func and getattr(other_func, "__doc__", None) is getattr(p_func, "__doc__", None):
                # _bisect.bisect == _bisect.bisect_right in py31, but docs differ
                out(indent, p_name, " = ", seen[id(p_func)])
                out(indent, "")
                return
            else:
                seen[id(p_func)] = p_name
                # real work
        if classname is None:
            classname = p_class and p_class.__name__ or None
        if p_class and hasattr(p_class, '__mro__'):
            sip_generated = [base_t for base_t in p_class.__mro__ if 'sip.simplewrapper' in str(base_t)]
        else:
            sip_generated = False
        deco = None
        deco_comment = ""
        mod_class_method_tuple = (p_modname, classname, p_name)
        ret_literal = None
        is_init = False
        # any decorators?
        action("redoing decos of func %r of class %r", p_name, p_class)
        if self.doing_builtins and p_modname == BUILTIN_MOD_NAME:
            deco = KNOWN_DECORATORS.get((classname, p_name), None)
            if deco:
                deco_comment = " # known case"
        elif p_class and p_name in p_class.__dict__:
            # detect native methods declared with METH_CLASS flag
            descriptor = p_class.__dict__[p_name]
            if p_name != "__new__" and type(descriptor).__name__.startswith('classmethod'):
                # 'classmethod_descriptor' in Python 2.x and 3.x, 'classmethod' in Jython
                deco = "classmethod"
            elif type(p_func).__name__.startswith('staticmethod'):
                deco = "staticmethod"
        if p_name == "__new__":
            deco = "staticmethod"
            deco_comment = " # known case of __new__"

        action("redoing innards of func %r of class %r", p_name, p_class)
        if deco and HAS_DECORATORS:
            out(indent, "@", deco, deco_comment)
        if inspect and inspect.isfunction(p_func):
            out(indent, "def ", p_name, restore_by_inspect(p_func), ": # reliably restored by inspect", )
            out_doc_attr(out, p_func, indent + 1, p_class)
        elif self.is_predefined_builtin(*mod_class_method_tuple):
            spec, sig_note = restore_predefined_builtin(classname, p_name)
            out(indent, "def ", spec, ": # ", sig_note)
            out_doc_attr(out, p_func, indent + 1, p_class)
        elif sys.platform == 'cli' and is_clr_type(p_class):
            is_static, spec, sig_note = restore_clr(p_name, p_class)
            if is_static:
                out(indent, "@staticmethod")
            if not spec: return
            if sig_note:
                out(indent, "def ", spec, ": #", sig_note)
            else:
                out(indent, "def ", spec, ":")
            if not p_name in ['__gt__', '__ge__', '__lt__', '__le__', '__ne__', '__reduce_ex__', '__str__']:
                out_doc_attr(out, p_func, indent + 1, p_class)
        elif mod_class_method_tuple in PREDEFINED_MOD_CLASS_SIGS:
            sig, ret_literal = PREDEFINED_MOD_CLASS_SIGS[mod_class_method_tuple]
            if classname:
                ofwhat = "%s.%s.%s" % mod_class_method_tuple
            else:
                ofwhat = "%s.%s" % (p_modname, p_name)
            out(indent, "def ", p_name, sig, ": # known case of ", ofwhat)
            out_doc_attr(out, p_func, indent + 1, p_class)
        else:
            # __doc__ is our best source of arglist
            sig_note = "real signature unknown"
            spec = ""
            is_init = (p_name == "__init__" and p_class is not None)
            funcdoc = None
            if is_init and hasattr(p_class, "__doc__"):
                if hasattr(p_func, "__doc__"):
                    funcdoc = p_func.__doc__
                if funcdoc == object.__init__.__doc__:
                    funcdoc = p_class.__doc__
            elif hasattr(p_func, "__doc__"):
                funcdoc = p_func.__doc__
            sig_restored = False
            action("parsing doc of func %r of class %r", p_name, p_class)
            if isinstance(funcdoc, STR_TYPES):
                (spec, ret_literal, more_notes) = self.parse_func_doc(funcdoc, p_name, p_name, classname, deco,
                                                                      sip_generated)
                if spec is None and p_name == '__init__' and classname:
                    (spec, ret_literal, more_notes) = self.parse_func_doc(funcdoc, classname, p_name, classname, deco,
                                                                          sip_generated)
                sig_restored = spec is not None
                if more_notes:
                    if sig_note:
                        sig_note += "; "
                    sig_note += more_notes
            if not sig_restored:
                # use an allow-all declaration
                decl = []
                if p_class:
                    first_param = propose_first_param(deco)
                    if first_param:
                        decl.append(first_param)
                decl.append("*args")
                decl.append("**kwargs")
                spec = p_name + "(" + ", ".join(decl) + ")"
            out(indent, "def ", spec, ": # ", sig_note)
            # to reduce size of stubs, don't output same docstring twice for class and its __init__ method
            if not is_init or funcdoc != p_class.__doc__:
                out_docstring(out, funcdoc, indent + 1)
                # body
        if ret_literal and not is_init:
            out(indent + 1, "return ", ret_literal)
        else:
            out(indent + 1, "pass")
        if deco and not HAS_DECORATORS:
            out(indent, p_name, " = ", deco, "(", p_name, ")", deco_comment)
        out(0, "") # empty line after each item


    def redo_class(self, out, p_class, p_name, indent, p_modname=None, seen=None, inspect_dir=False):
        """
        Restores a class definition.
        @param out output function of a relevant buf
        @param p_class the class object
        @param p_name class name as known to owner
        @param indent indentation level
        @param p_modname name of module
        @param seen {class: name} map of classes already seen in the same namespace
        """
        action("redoing class %r of module %r", p_name, p_modname)
        if seen is not None:
            if p_class in seen:
                out(indent, p_name, " = ", seen[p_class])
                out(indent, "")
                return
            else:
                seen[p_class] = p_name
        bases = get_bases(p_class)
        base_def = ""
        skipped_bases = []
        if bases:
            skip_qualifiers = [p_modname, BUILTIN_MOD_NAME, 'exceptions']
            skip_qualifiers.extend(KNOWN_FAKE_REEXPORTERS.get(p_modname, ()))
            bases_list = [] # what we'll render in the class decl
            for base in bases:
                if [1 for (cls, mdl) in KNOWN_FAKE_BASES if cls == base and mdl != self.module]:
                    # our base is a wrapper and our module is not its defining module
                    skipped_bases.append(str(base))
                    continue
                    # somehow import every base class
                base_name = base.__name__
                qual_module_name = qualifier_of(base, skip_qualifiers)
                got_existing_import = False
                if qual_module_name:
                    if qual_module_name in self.used_imports:
                        import_list = self.used_imports[qual_module_name]
                        if base in import_list:
                            bases_list.append(base_name) # unqualified: already set to import
                            got_existing_import = True
                    if not got_existing_import:
                        mangled_qualifier = "__" + qual_module_name.replace('.', '_') # foo.bar -> __foo_bar
                        bases_list.append(mangled_qualifier + "." + base_name)
                        self.hidden_imports[qual_module_name] = mangled_qualifier
                else:
                    bases_list.append(base_name)
            base_def = "(" + ", ".join(bases_list) + ")"

            for base in bases_list:
                local_import = self.create_local_import(base)
                if local_import:
                    out(indent, local_import)
        out(indent, "class ", p_name, base_def, ":",
            skipped_bases and " # skipped bases: " + ", ".join(skipped_bases) or "")
        out_doc_attr(out, p_class, indent + 1)
        # inner parts
        methods = {}
        properties = {}
        others = {}
        we_are_the_base_class = p_modname == BUILTIN_MOD_NAME and p_name == "object"
        field_source = {}
        try:
            if hasattr(p_class, "__dict__") and not inspect_dir:
                field_source = p_class.__dict__
                field_keys = field_source.keys() # Jython 2.5.1 _codecs fail here
            else:
                field_keys = dir(p_class) # this includes unwanted inherited methods, but no dict + inheritance is rare
        except:
            field_keys = ()
        for item_name in field_keys:
            if item_name in ("__doc__", "__module__"):
                if we_are_the_base_class:
                    item = "" # must be declared in base types
                else:
                    continue # in all other cases must be skipped
            elif keyword.iskeyword(item_name):  # for example, PyQt4 contains definitions of methods named 'exec'
                continue
            else:
                try:
                    item = getattr(p_class, item_name) # let getters do the magic
                except AttributeError:
                    item = field_source[item_name] # have it raw
                except Exception:
                    continue
            if is_callable(item) and not isinstance(item, type):
                methods[item_name] = item
            elif is_property(item):
                properties[item_name] = item
            else:
                others[item_name] = item
                #
        if we_are_the_base_class:
            others["__dict__"] = {} # force-feed it, for __dict__ does not contain a reference to itself :)
            # add fake __init__s to have the right sig
        if p_class in FAKE_BUILTIN_INITS:
            methods["__init__"] = self.fake_builtin_init
            note("Faking init of %s", p_name)
        elif '__init__' not in methods:
            init_method = getattr(p_class, '__init__', None)
            if init_method:
                methods['__init__'] = init_method

        #
        seen_funcs = {}
        for item_name in sorted_no_case(methods.keys()):
            item = methods[item_name]
            try:
                self.redo_function(out, item, item_name, indent + 1, p_class, p_modname, classname=p_name, seen=seen_funcs)
            except:
                handle_error_func(item_name, out)
                #
        known_props = KNOWN_PROPS.get(p_modname, {})
        a_setter = "lambda self, v: None"
        a_deleter = "lambda self: None"
        for item_name in sorted_no_case(properties.keys()):
            item = properties[item_name]
            prop_docstring = getattr(item, '__doc__', None)
            prop_key = (p_name, item_name)
            if prop_key in known_props:
                prop_descr = known_props.get(prop_key, None)
                if prop_descr is None:
                    continue # explicitly omitted
                acc_line, getter_and_type = prop_descr
                if getter_and_type:
                    getter, prop_type = getter_and_type
                else:
                    getter, prop_type = None, None
                out(indent + 1, item_name,
                    " = property(", format_accessors(acc_line, getter, a_setter, a_deleter), ")"
                )
                if prop_type:
                    if prop_docstring:
                        out(indent + 1, '"""', prop_docstring)
                        out(0, "")
                        out(indent + 1, ':type: ', prop_type)
                        out(indent + 1, '"""')
                    else:
                        out(indent + 1, '""":type: ', prop_type, '"""')
                    out(0, "")
            else:
                out(indent + 1, item_name, " = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default")
                if prop_docstring:
                    out(indent + 1, '"""', prop_docstring, '"""')
                out(0, "")
        if properties:
            out(0, "") # empty line after the block
            #
        for item_name in sorted_no_case(others.keys()):
            item = others[item_name]
            self.fmt_value(out, item, indent + 1, prefix=item_name + " = ")
        if p_name == "object":
            out(indent + 1, "__module__ = ''")
        if others:
            out(0, "") # empty line after the block
            #
        if not methods and not properties and not others:
            out(indent + 1, "pass")



    def redo_simple_header(self, p_name):
        """Puts boilerplate code on the top"""
        out = self.header_buf.out # 1st class methods rule :)
        out(0, "# encoding: %s" % OUT_ENCODING) # line 1
        # NOTE: maybe encoding should be selectable
        if hasattr(self.module, "__name__"):
            self_name = self.module.__name__
            if self_name != p_name:
                mod_name = " calls itself " + self_name
            else:
                mod_name = ""
        else:
            mod_name = " does not know its name"
        out(0, "# module ", p_name, mod_name) # line 2

        BUILT_IN_HEADER = "(built-in)"
        if self.mod_filename:
            filename = self.mod_filename
        elif p_name in sys.builtin_module_names:
            filename = BUILT_IN_HEADER
        else:
            filename = getattr(self.module, "__file__", BUILT_IN_HEADER)

        out(0, "# from %s" % filename)  # line 3
        out(0, "# by generator %s" % VERSION) # line 4
        if p_name == BUILTIN_MOD_NAME and version[0] == 2 and version[1] >= 6:
            out(0, "from __future__ import print_function")
        out_doc_attr(out, self.module, 0)


    def redo_imports(self):
        module_type = type(sys)
        for item_name in self.module.__dict__.keys():
            try:
                item = self.module.__dict__[item_name]
            except:
                continue
            if type(item) is module_type: # not isinstance, py2.7 + PyQt4.QtCore on windows have a bug here
                self.imported_modules[item_name] = item
                self.add_import_header_if_needed()
                ref_notice = getattr(item, "__file__", str(item))
                if hasattr(item, "__name__"):
                    self.imports_buf.out(0, "import ", item.__name__, " as ", item_name, " # ", ref_notice)
                else:
                    self.imports_buf.out(0, item_name, " = None # ??? name unknown; ", ref_notice)

    def add_import_header_if_needed(self):
        if self.imports_buf.isEmpty():
            self.imports_buf.out(0, "")
            self.imports_buf.out(0, "# imports")


    def redo(self, p_name, inspect_dir):
        """
        Restores module declarations.
        Intended for built-in modules and thus does not handle import statements.
        @param p_name name of module
        """
        action("redoing header of module %r %r", p_name, str(self.module))

        if "pyqt4" in p_name.lower():   # qt4 specific patch
            self._initializeQApp4()
        elif "pyqt5" in p_name.lower():   # qt5 specific patch
            self._initializeQApp5()

        self.redo_simple_header(p_name)

        # find whatever other self.imported_modules the module knows; effectively these are imports
        action("redoing imports of module %r %r", p_name, str(self.module))
        try:
            self.redo_imports()
        except:
            pass

        action("redoing innards of module %r %r", p_name, str(self.module))

        module_type = type(sys)
        # group what we have into buckets
        vars_simple = {}
        vars_complex = {}
        funcs = {}
        classes = {}
        module_dict = self.module.__dict__
        if inspect_dir:
            module_dict = dir(self.module)
        for item_name in module_dict:
            note("looking at %s", item_name)
            if item_name in (
                "__dict__", "__doc__", "__module__", "__file__", "__name__", "__builtins__", "__package__"):
                continue # handled otherwise
            try:
                item = getattr(self.module, item_name) # let getters do the magic
            except AttributeError:
                if not item_name in self.module.__dict__: continue
                item = self.module.__dict__[item_name] # have it raw
                # check if it has percolated from an imported module
            except NotImplementedError:
                if not item_name in self.module.__dict__: continue
                item = self.module.__dict__[item_name] # have it raw

            # unless we're adamantly positive that the name was imported, we assume it is defined here
            mod_name = None # module from which p_name might have been imported
            # IronPython has non-trivial reexports in System module, but not in others:
            skip_modname = sys.platform == "cli" and p_name != "System"
            surely_not_imported_mods = KNOWN_FAKE_REEXPORTERS.get(p_name, ())
            ## can't figure weirdness in some modules, assume no reexports:
            #skip_modname =  skip_modname or p_name in self.KNOWN_FAKE_REEXPORTERS
            if not skip_modname:
                try:
                    mod_name = getattr(item, '__module__', None)
                except:
                    pass
                    # we assume that module foo.bar never imports foo; foo may import foo.bar. (see pygame and pygame.rect)
            maybe_import_mod_name = mod_name or ""
            import_is_from_top = len(p_name) > len(maybe_import_mod_name) and p_name.startswith(maybe_import_mod_name)
            note("mod_name = %s, prospective = %s,  from top = %s", mod_name, maybe_import_mod_name, import_is_from_top)
            want_to_import = False
            if (mod_name
                and mod_name != BUILTIN_MOD_NAME
                and mod_name != p_name
                and mod_name not in surely_not_imported_mods
                and not import_is_from_top
            ):
                # import looks valid, but maybe it's a .py file? we're certain not to import from .py
                # e.g. this rules out _collections import collections and builtins import site.
                try:
                    imported = __import__(mod_name) # ok to repeat, Python caches for us
                    if imported:
                        qualifiers = mod_name.split(".")[1:]
                        for qual in qualifiers:
                            imported = getattr(imported, qual, None)
                            if not imported:
                                break
                        imported_path = (getattr(imported, '__file__', False) or "").lower()
                        want_to_import = not (imported_path.endswith('.py') or imported_path.endswith('.pyc'))
                        note("path of %r is %r, want? %s", mod_name, imported_path, want_to_import)
                except ImportError:
                    want_to_import = False
                    # NOTE: if we fail to import, we define 'imported' names here lest we lose them at all
                if want_to_import:
                    import_list = self.used_imports[mod_name]
                    if item_name not in import_list:
                        import_list.append(item_name)
            if not want_to_import:
                if isinstance(item, type) or type(item).__name__ == 'classobj':
                    classes[item_name] = item
                elif is_callable(item): # some classes are callable, check them before functions
                    funcs[item_name] = item
                elif isinstance(item, module_type):
                    continue # self.imported_modules handled above already
                else:
                    if isinstance(item, SIMPLEST_TYPES):
                        vars_simple[item_name] = item
                    else:
                        vars_complex[item_name] = item

        # sort and output every bucket
        action("outputting innards of module %r %r", p_name, str(self.module))
        #
        omitted_names = OMIT_NAME_IN_MODULE.get(p_name, [])
        if vars_simple:
            out = self.functions_buf.out
            prefix = "" # try to group variables by common prefix
            PREFIX_LEN = 2 # default prefix length if we can't guess better
            out(0, "# Variables with simple values")
            for item_name in sorted_no_case(vars_simple.keys()):
                if item_name in omitted_names:
                    out(0, "# definition of " + item_name + " omitted")
                    continue
                item = vars_simple[item_name]
                # track the prefix
                if len(item_name) >= PREFIX_LEN:
                    prefix_pos = string.rfind(item_name, "_") # most prefixes end in an underscore
                    if prefix_pos < 1:
                        prefix_pos = PREFIX_LEN
                    beg = item_name[0:prefix_pos]
                    if prefix != beg:
                        out(0, "") # space out from other prefix
                        prefix = beg
                else:
                    prefix = ""
                    # output
                replacement = REPLACE_MODULE_VALUES.get((p_name, item_name), None)
                if replacement is not None:
                    out(0, item_name, " = ", replacement, " # real value of type ", str(type(item)), " replaced")
                elif is_skipped_in_module(p_name, item_name):
                    t_item = type(item)
                    out(0, item_name, " = ", self.invent_initializer(t_item), " # real value of type ", str(t_item),
                        " skipped")
                else:
                    self.fmt_value(out, item, 0, prefix=item_name + " = ")
                self._defined[item_name] = True
            out(0, "") # empty line after vars
            #
        if funcs:
            out = self.functions_buf.out
            out(0, "# functions")
            out(0, "")
            seen_funcs = {}
            for item_name in sorted_no_case(funcs.keys()):
                if item_name in omitted_names:
                    out(0, "# definition of ", item_name, " omitted")
                    continue
                item = funcs[item_name]
                try:
                    self.redo_function(out, item, item_name, 0, p_modname=p_name, seen=seen_funcs)
                except:
                    handle_error_func(item_name, out)
        else:
            self.functions_buf.out(0, "# no functions")
            #
        if classes:
            self.classes_buf.out(0, "# classes")
            self.classes_buf.out(0, "")
            seen_classes = {}
            # sort classes so that inheritance order is preserved
            cls_list = [] # items are (class_name, mro_tuple)
            for cls_name in sorted_no_case(classes.keys()):
                cls = classes[cls_name]
                ins_index = len(cls_list)
                for i in range(ins_index):
                    maybe_child_bases = cls_list[i][1]
                    if cls in maybe_child_bases:
                        ins_index = i # we could not go farther than current ins_index
                        break         # ...and need not go fartehr than first known child
                cls_list.insert(ins_index, (cls_name, get_mro(cls)))
            self.split_modules = self.mod_filename and len(cls_list) >= 30
            for item_name in [cls_item[0] for cls_item in cls_list]:
                buf = ClassBuf(item_name, self)
                self.classes_buffs.append(buf)
                out = buf.out
                if item_name in omitted_names:
                    out(0, "# definition of ", item_name, " omitted")
                    continue
                item = classes[item_name]
                self.redo_class(out, item, item_name, 0, p_modname=p_name, seen=seen_classes, inspect_dir=inspect_dir)
                self._defined[item_name] = True
                out(0, "") # empty line after each item

            if self.doing_builtins and p_name == BUILTIN_MOD_NAME and version[0] < 3:
                # classobj still supported
                txt = classobj_txt
                self.classes_buf.out(0, txt)

            if self.doing_builtins and p_name == BUILTIN_MOD_NAME:
                txt = create_generator()
                self.classes_buf.out(0, txt)
                txt = create_function()
                self.classes_buf.out(0, txt)
                txt = create_method()
                self.classes_buf.out(0, txt)

                # Fake <type 'namedtuple'>
                if version[0] >= 3 or (version[0] == 2 and version[1] >= 6):
                    namedtuple_text = create_named_tuple()
                    self.classes_buf.out(0, namedtuple_text)

        else:
            self.classes_buf.out(0, "# no classes")
            #
        if vars_complex:
            out = self.footer_buf.out
            out(0, "# variables with complex values")
            out(0, "")
            for item_name in sorted_no_case(vars_complex.keys()):
                if item_name in omitted_names:
                    out(0, "# definition of " + item_name + " omitted")
                    continue
                item = vars_complex[item_name]
                if str(type(item)) == "<type 'namespace#'>":
                    continue            # this is an IronPython submodule, we mustn't generate a reference for it in the base module
                replacement = REPLACE_MODULE_VALUES.get((p_name, item_name), None)
                if replacement is not None:
                    out(0, item_name + " = " + replacement + " # real value of type " + str(type(item)) + " replaced")
                elif is_skipped_in_module(p_name, item_name):
                    t_item = type(item)
                    out(0, item_name + " = " + self.invent_initializer(t_item) + " # real value of type " + str(
                        t_item) + " skipped")
                else:
                    self.fmt_value(out, item, 0, prefix=item_name + " = ", as_name=item_name)
                self._defined[item_name] = True
                out(0, "") # empty line after each item
        values_to_add = ADD_VALUE_IN_MODULE.get(p_name, None)
        if values_to_add:
            self.footer_buf.out(0, "# intermittent names")
            for value in values_to_add:
                self.footer_buf.out(0, value)
                # imports: last, because previous parts could alter used_imports or hidden_imports
        self.output_import_froms()
        if self.imports_buf.isEmpty():
            self.imports_buf.out(0, "# no imports")
        self.imports_buf.out(0, "") # empty line after imports

    def output_import_froms(self):
        """Mention all imported names known within the module, wrapping as per PEP."""
        out = self.imports_buf.out
        if self.used_imports:
            self.add_import_header_if_needed()
            for mod_name in sorted_no_case(self.used_imports.keys()):
                import_names = self.used_imports[mod_name]
                if import_names:
                    self._defined[mod_name] = True
                    right_pos = 0 # tracks width of list to fold it at right margin
                    import_heading = "from % s import (" % mod_name
                    right_pos += len(import_heading)
                    names_pack = [import_heading]
                    indent_level = 0
                    import_names = list(import_names)
                    import_names.sort()
                    for n in import_names:
                        self._defined[n] = True
                        len_n = len(n)
                        if right_pos + len_n >= 78:
                            out(indent_level, *names_pack)
                            names_pack = [n, ", "]
                            if indent_level == 0:
                                indent_level = 1 # all but first line is indented
                            right_pos = self.indent_size + len_n + 2
                        else:
                            names_pack.append(n)
                            names_pack.append(", ")
                            right_pos += (len_n + 2)
                            # last line is...
                    if indent_level == 0: # one line
                        names_pack[0] = names_pack[0][:-1] # cut off lpar
                        names_pack[-1] = "" # cut last comma
                    else: # last line of multiline
                        names_pack[-1] = ")" # last comma -> rpar
                    out(indent_level, *names_pack)

                    out(0, "") # empty line after group

        if self.hidden_imports:
            self.add_import_header_if_needed()
            for mod_name in sorted_no_case(self.hidden_imports.keys()):
                out(0, 'import ', mod_name, ' as ', self.hidden_imports[mod_name])
            out(0, "") # empty line after group


def module_to_package_name(module_name):
    return re.sub(r"(.*)\.py$", r"\1", module_name)
