# Tests for functions without parameters or a dangling comment
# Black's overall behavior is to:
# 1. Print the return type on the same line as the function header if it fits
# 2. Parenthesize the return type if it doesn't fit.
# The exception to this are subscripts, see below


#########################################################################################
# Return types that use NeedsParantheses::BestFit layout with the exception of subscript
#########################################################################################
# String return type that fits on the same line
def no_parameters_string_return_type() -> "ALongIdentifierButDoesntGetParenthesized":
    pass


# String return type that exceeds the line length
def no_parameters_overlong_string_return_type() -> (
    "ALongIdentifierButDoesntGetParenthesized"
):
    pass


# Name return type that fits on the same line as the function header
def no_parameters_name_return_type() -> ALongIdentifierButDoesntGetParenthesized:
    pass


# Name return type that exceeds the configured line width
def no_parameters_overlong_name_return_type() -> (
    ALongIdentifierButDoesntGetParenthesized
):
    pass



#########################################################################################
# Unions
#########################################################################################

def test_return_overlong_union() -> (
    A | B | C | DDDDDDDDDDDDDDDDDDDDDDDD | EEEEEEEEEEEEEEEEEEEEEE
):
    pass



def test_return_union_with_elements_exceeding_length() -> (
    A
    | B
    | Ccccccccccccccccccccccccccccccccc
    | DDDDDDDDDDDDDDDDDDDDDDDD
    | EEEEEEEEEEEEEEEEEEEEEE
):
    pass



#########################################################################################
# Multiline strings (NeedsParentheses::Never)
#########################################################################################

def test_return_multiline_string_type_annotation() -> """str
    | list[str]
""":
    pass


def test_return_multiline_string_binary_expression_return_type_annotation() -> """str
    | list[str]
""" + "b":
    pass


#########################################################################################
# Implicit concatenated strings (NeedsParentheses::Multiline)
#########################################################################################


def test_implicit_concatenated_string_return_type() -> "str" "bbbbbbbbbbbbbbbb":
    pass


def test_overlong_implicit_concatenated_string_return_type() -> (
    "liiiiiiiiiiiisssssst[str]" "bbbbbbbbbbbbbbbb"
):
    pass


def test_extralong_implicit_concatenated_string_return_type() -> (
    "liiiiiiiiiiiisssssst[str]"
    "bbbbbbbbbbbbbbbbbbbb"
    "cccccccccccccccccccccccccccccccccccccc"
):
    pass


#########################################################################################
# Subscript
#########################################################################################
def no_parameters_subscript_return_type() -> list[str]:
    pass


# 1. Black tries to keep the list flat by parenthesizing the list as shown below even when the `list` identifier
#    fits on the header line. IMO, this adds unnecessary parentheses that can be avoided
#    and supporting it requires extra complexity (best_fitting! layout)
def no_parameters_overlong_subscript_return_type_with_single_element() -> (
    list[xxxxxxxxxxxxxxxxxxxxx]
):
    pass


# 2. Black: Removes the parentheses when the subscript fits after breaking individual elements.
#    This is somewhat wasteful because the below list actually fits on a single line when splitting after
#    `list[`. It is also inconsistent with how subscripts are normally formatted where it first tries to fit the entire subscript,
#     then splits after `list[` but keeps all elements on a single line, and finally, splits after each element.
# IMO: Splitting after the `list[` and trying to keep the elements together when possible seems more consistent.
def no_parameters_subscript_return_type_multiple_elements() -> list[
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
]:
    pass


# Black removes the parentheses even the elements exceed the configured line width.
# So does Ruff.
def no_parameters_subscript_return_type_multiple_overlong_elements() -> list[
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
]:
    pass


# Black parenthesizes the subscript if its name doesn't fit on the header line.
# So does Ruff
def no_parameters_subscriptreturn_type_with_overlong_value_() -> (
    liiiiiiiiiiiiiiiiiiiiist[
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ]
):
    pass


# Black: It removes the parentheses when the subscript contains multiple elements as
# `no_parameters_subscript_return_type_multiple_overlong_elements` shows. However, it doesn't
# when the subscript contains a single element. Black then keeps the parentheses.
# Ruff removes the parentheses in this case for consistency.
def no_parameters_overlong_subscript_return_type_with_overlong_single_element() -> (
    list[
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ]
):
    pass


#########################################################################################
# can_omit_optional_parentheses_layout
#########################################################################################

def test_binary_expression_return_type_annotation() -> aaaaaaaaaaaaaaaaaaaaaaaaaa > [
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
    bbbbbbbbbbbbbbbbbbbbbbbbb,
]:
    pass


#########################################################################################
# Other
#########################################################################################

# Don't paranthesize lists
def f() -> [
    a,
    b,
]: pass
