"""Tests for empty line rules in stub files, mostly inspired by typeshed.
The rules are a list of nested exceptions. See also
https://github.com/psf/black/blob/c160e4b7ce30c661ac4f2dfa5038becf1b8c5c33/src/black/lines.py#L576-L744
"""

import sys
from typing import Self, TypeAlias, final

if sys.version_info >= (3, 8):
    class InnerClass1: ...

    class InnerClass2:
        def a(self): ...

    class InnerClass3:
        def a(self): ...

    class InnerClass4: ...
    details: int
    def f1(self, hresult: int, text: str | None, detail: int) -> None: ...
    details: int
    def f2(self, hresult: int, text: str | None, detail: int) -> None: ...
    @final
    class DecoratorInsteadOfEmptyLine: ...

    def open(device: str) -> None: ...

    # oss_mixer_device return type
    def openmixer(device: str = ...) -> None: ...
    def open2(device: str) -> None: ...
    # oss_mixer_device2 return type
    def openmixer2(device: str = ...) -> None: ...

else:
    class Slice1: ...
    _Slice1: TypeAlias = Slice1

    class Slice2: ...
    _Slice2: TypeAlias = Slice2

class NoEmptyLinesBetweenFunctions:
    def multi_line_but_only_ellipsis(
        self,
        mandatory_release: float | None,
    ) -> None: ...
    def only_ellipsis1(self) -> float: ...
    def only_ellipsis2(self) -> float | None: ...
    def has_impl1(self):
        print(self)
        return 1

    def has_impl2(self):
        print(self)
        return 2

    def no_impl4(self): ...

class NoEmptyLinesBetweenField:
    field1: int
    field2: (
        # type
        int
    )
    field3 = 3
    field4 = (
        1,
        2,
    )
    field5 = 5

class FieldAndFunctionsWithOptionalEmptyLines:
    details1: int
    def f1(self, hresult: int, text: str | None, detail: int) -> None: ...
    details2: int
    def f2(self, hresult: int, text: str | None, detail: int) -> None: ...
    details3: int

class NewlinesBetweenStubInnerClasses:
    def f1(self): ...

    class InnerClass1: ...
    class InnerClass2: ...

    def f2(self): ...

    class InnerClass3: ...
    class InnerClass4: ...
    field = 1

    class InnerClass3: ...
    class InnerClass4: ...

    def f3(self): ...
    @final
    class DecoratorInsteadOfEmptyLine: ...

    @final
    class DecoratorStillEmptyLine: ...

class NewlinesBetweenInnerClasses:
    class InnerClass1: ...

    class InnerClass2:
        def a(self): ...

    class InnerClass3:
        def a(self): ...

    class InnerClass4: ...

    class InnerClass5:
        def a(self): ...
    field1 = 1

    class InnerClass6:
        def a(self): ...

    def f1(self): ...

    class InnerClass7:
        def a(self): ...
    print("hi")

    class InnerClass8:
        def a(self): ...

class ComplexStatements:
    # didn't match the name in the C implementation,
    # meaning it is only *safe* to pass it as a keyword argument on 3.12+
    if sys.version_info >= (3, 12):
        @classmethod
        def fromtimestamp(cls, timestamp: float, tz: float | None = ...) -> Self: ...
    else:
        @classmethod
        def fromtimestamp(cls, __timestamp: float, tz: float | None = ...) -> Self: ...

    @classmethod
    def utcfromtimestamp(cls, __t: float) -> Self: ...
    if sys.version_info >= (3, 8):
        @classmethod
        def now(cls, tz: float | None = None) -> Self: ...
    else:
        @classmethod
        def now(cls, tz: None = None) -> Self: ...
        @classmethod
        def now2(cls, tz: float) -> Self: ...

    @classmethod
    def utcnow(cls) -> Self: ...
