# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from __future__ import annotations

import os
import sys
import unittest

from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)

from helper.usesqapplication import UsesQApplication
from PySide6 import QtCore, QtGui, QtWidgets
from PySide6.QtWidgets import QMainWindow, QLabel, QWidget


def xprint(*args, **kw):
    if "-v" in sys.argv:
        print(*args, **kw)


# This is the original testcase of PYSIDE-1564
class Age:
    def __init__(self, age=0, **kwds):
        super().__init__(**kwds)

        self.age = age


class Person(QtCore.QObject, Age):
    def __init__(self, name, **kwds):
        super().__init__(**kwds)

        self.name = name


class OriginalMultipleInheritanceTest(unittest.TestCase):

    def testIt(self):
        xprint()
        p = Person("Joe", age=38)
        xprint(f"p.age = {p.age}")
        # This would crash if MI does not work.

# More tests follow:


# mro ('C', 'A', 'QObject', 'Object', 'B', 'object')
class A(QtCore.QObject):
    def __init__(self, anna=77, **kw):
        xprint(f'A: before init kw = {kw}')
        super().__init__(**kw)
        xprint('A: after init')


class B:
    def __init__(self, otto=6, age=7, **kw):
        xprint(f'B: before init kw = {kw}')
        if "killme" in kw:
            raise AssertionError("asdf")
        super().__init__(**kw)
        self.age = age
        xprint('B: after init')


class C(A, B):
    def __init__(self, **kw):
        xprint(f'C: before init kw = {kw}')
        super().__init__(**kw)
        xprint('C: after init')


# mro ('F', 'D', 'QCursor', 'E', 'QLabel', 'QFrame', 'QWidget', 'QObject',
#      'QPaintDevice', 'Object', 'object')
class D(QtGui.QCursor):
    def __init__(self, anna=77, **kw):
        xprint(f'D: before init kw = {kw}')
        super().__init__(**kw)
        xprint('D: after init')


class E:
    def __init__(self, age=7, **kw):
        xprint(f'E: before init kw = {kw}')
        super().__init__(**kw)
        self.age = age
        xprint('E: after init')


class F(D, E, QtWidgets.QLabel):
    def __init__(self, **kw):
        xprint(f'F: before init kw = {kw}')
        super().__init__(**kw)
        xprint('F: after init')


# mro ('I', 'G', 'QTextDocument', 'H', 'QLabel', 'QFrame', 'QWidget', 'QObject',
#      'QPaintDevice', 'Object', 'object')
# Similar, but this time we want to reach `H` without support from `super`.
class G(QtGui.QTextDocument):
    pass


class H:
    def __init__(self, age=7, **kw):
        xprint(f'H: before init kw = {kw}')
        super().__init__(**kw)
        self.age = age
        xprint('H: after init')


class II(G, H, QtWidgets.QLabel):
    pass


# PYSIDE-2294: Friedemann's test adapted.
#              We need to ignore positional args in mixin classes.
class Ui_X_MainWindow:  # Emulating uic
    def setupUi(self, MainWindow):
        MainWindow.resize(400, 300)
        self.lbl = QLabel(self)


class MainWindow(QMainWindow, Ui_X_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)


class AdditionalMultipleInheritanceTest(UsesQApplication):

    def testABC(self):
        xprint()
        res = C(otto=3, anna=5)
        self.assertEqual(res.age, 7)
        xprint()
        with self.assertRaises(AssertionError):
            res = C(killme=42)
        xprint()

    def testDEF(self):
        xprint()
        res = F(anna=5)
        self.assertEqual(res.age, 7)
        xprint()

    def testGHI(self):
        xprint()
        res = II(age=7)
        self.assertEqual(res.age, 7)
        xprint()

    def testParentDoesNotCrash(self):
        # This crashed with
        # TypeError: object.__init__() takes exactly one argument (the instance to initialize)
        MainWindow()


# PYSIDE-2654: Additional missing init test.
#              This must work if no __init__ is defined (Ui_Form)
class Ui_Form:
    pass


class Mixin:
    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)


class Card(Mixin, QWidget):
    def __init__(self, parent=None) -> None:
        super().__init__(parent=parent)


class Demo(Card, Ui_Form):
    def __init__(self) -> None:
        super().__init__()


class MissingInitFunctionTest(UsesQApplication):
    def testMissing(self):
        Demo()
        # Tests if this works. Would crash without the extra
        # check for object.__init__


if __name__ == "__main__":
    unittest.main()
