import ast

import python_pyi

w = python_pyi.Widget(42)
if w.getId() != 42:
    raise RuntimeError("Widget.getId() returned the wrong value")
if python_pyi.Widget.create(7).getId() != 7:
    raise RuntimeError("Widget.create() returned the wrong value")
if python_pyi.OverloadedWidget.create(7).getId() != 7:
    raise RuntimeError("OverloadedWidget.create() returned the wrong value")
if python_pyi.OverloadedWidget.create(7, 3).getId() != 10:
    raise RuntimeError("OverloadedWidget.create() returned the wrong value for the second overload")

with open("python_pyi.pyi") as f:
    source = f.read()

# Must always be syntactically valid Python.
tree = ast.parse(source, filename="python_pyi.pyi")

names = set()
for node in ast.walk(tree):
    if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
        names.add(node.name)
    elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
        names.add(node.target.id)

# Everything expected from a -builtin class should appear in the stub.
expected = {"Empty", "SizedCollection", "Widget", "__init__", "getId", "create", "id", "make_unwrapped", "SWIGTYPE_p_Unwrapped"}
missing = expected - names
if missing:
    raise RuntimeError("python_pyi.pyi is missing expected declarations: %s" % sorted(missing))

# An overloaded method is declared with **kwargs as well as *args, so that it stays assignable to the one it hides.
for node in ast.walk(tree):
    if isinstance(node, ast.ClassDef) and node.name == "OverloadedWidget":
        for method in node.body:
            if isinstance(method, ast.FunctionDef) and method.name == "create" and method.args.kwarg is None:
                raise RuntimeError("python_pyi.pyi should declare OverloadedWidget.create with **kwargs")

# The opaque type wrapper class is only ever generated into the .pyi file.
classes = {node.name for node in ast.walk(tree) if isinstance(node, ast.ClassDef)}
if "SWIGTYPE_p_Unwrapped" not in classes:
    raise RuntimeError("python_pyi.pyi should declare the SWIGTYPE_p_Unwrapped class")

# %pythonstubcode inserted the import needed by the collections.abc base class.
if "import collections.abc" not in source:
    raise RuntimeError("python_pyi.pyi is missing the collections.abc import")

# %pythonstubbegin inserted its code at the top of the stub, before any real code.
marker = "# Generated by %pythonstubbegin"
if marker not in source:
    raise RuntimeError("python_pyi.pyi is missing the %pythonstubbegin code")
if source.index(marker) > source.index("import typing"):
    raise RuntimeError("python_pyi.pyi has the %pythonstubbegin code after the import typing statement")

# TYPE_CHECKING is meaningless in a .pyi (it is never executed, only read by
# a type checker), so SWIGTYPE_p_Unwrapped must not be guarded by it there.
if "TYPE_CHECKING" in source:
    raise RuntimeError("python_pyi.pyi should not guard anything with typing.TYPE_CHECKING")

# The low-level module stub declares everything the module exports, so it must not be marked incomplete.
with open("_python_pyi.pyi") as f:
    if "__getattr__" in f.read():
        raise RuntimeError("_python_pyi.pyi should declare every export instead of a catch-all __getattr__")

with open("python_pyi.py") as f:
    py_source = f.read()
py_tree = ast.parse(py_source, filename="python_pyi.py")

# The .py file keeps just the guarded 'this' declaration, which __disown__ needs to type check.
# There are no proxy classes at all to declare it in when -builtin is used.
py_classes = [node for node in ast.walk(py_tree) if isinstance(node, ast.ClassDef)]
if py_classes and "if typing.TYPE_CHECKING:" not in py_source:
    raise RuntimeError("python_pyi.py should declare 'this' guarded by typing.TYPE_CHECKING")
for node in ast.walk(py_tree):
    if isinstance(node, ast.AnnAssign) and getattr(node.target, "id", None) != "this":
        raise RuntimeError("python_pyi.py should have no variable annotations except 'this' when -pyi is used")
    # _swig_dispatch is type checker plumbing for the overload dispatchers in this file, not an annotation of the wrapped API.
    if isinstance(node, ast.FunctionDef) and node.name != "_swig_dispatch" and (node.returns is not None or any(a.annotation is not None for a in node.args.args)):
        raise RuntimeError("python_pyi.py should have no function annotations when -pyi is used")

# The type wrapper classes only exist to give an annotation a name, and the annotations are in the stub.
if "SWIGTYPE_p_Unwrapped" in py_source:
    raise RuntimeError("python_pyi.py should not declare SWIGTYPE_p_Unwrapped when -pyi is used")
