from starmerge import (
    create_tailwind_merge,
    extend_tailwind_merge,
    from_theme,
    get_default_config,
    merge,
    merge_configs,
    tw_join,
    validators,
)


def test_has_correct_export_types():
    assert callable(merge)
    assert callable(create_tailwind_merge)
    assert callable(get_default_config)

    # Check validators object has all expected methods
    validator_methods = [
        "is_any",
        "is_arbitrary_image",
        "is_arbitrary_length",
        "is_arbitrary_number",
        "is_arbitrary_position",
        "is_arbitrary_shadow",
        "is_arbitrary_size",
        "is_arbitrary_value",
        "is_arbitrary_variable",
        "is_fraction",
        "is_integer",
        "is_length",
        "is_length_only",
        "is_never",
        "is_number",
        "is_percent",
        "is_shadow",
        "is_tshirt_size",
        "is_image",
    ]

    for method in validator_methods:
        assert callable(getattr(validators, method))
    assert callable(merge_configs)
    assert callable(extend_tailwind_merge)
    assert callable(tw_join)


def test_twmerge_has_correct_inputs_and_outputs():
    assert isinstance(merge(""), str)
    assert isinstance(merge("hello world"), str)
    assert isinstance(merge("-:-:-:::---h-"), str)
    assert isinstance(merge("hello world", "-:-:-:::---h-"), str)
    assert isinstance(merge("hello world", "-:-:-:::---h-", "", "something"), str)
    assert isinstance(merge("hello world", None), str)
    assert isinstance(merge("hello world", None, None), str)
    assert isinstance(merge("hello world", None, None, False), str)
    assert isinstance(merge("hello world", [None], [None, False]), str)
    assert isinstance(
        merge("hello world", [None], [None, [False, "some-class"], []]), str
    )


def test_createtailwindmerge_has_correct_inputs_and_outputs():
    assert callable(create_tailwind_merge(get_default_config))
    assert callable(
        create_tailwind_merge(
            lambda: {
                "cache_size": 0,
                "theme": {},
                "class_groups": {},
                "conflicting_class_groups": {},
                "conflicting_class_group_modifiers": {},
                "order_sensitive_modifiers": [],
            }
        )
    )

    tailwind_merge = create_tailwind_merge(
        lambda: {
            "cache_size": 20,
            "theme": {},
            "class_groups": {
                "fooKey": [{"fooKey": ["bar", "baz"]}],
                "fooKey2": [{"fooKey": ["qux", "quux"]}],
                "otherKey": ["nother", "group"],
            },
            "conflicting_class_groups": {
                "fooKey": ["otherKey"],
                "otherKey": ["fooKey", "fooKey2"],
            },
            "conflicting_class_group_modifiers": {},
            "order_sensitive_modifiers": [],
        }
    )

    assert callable(tailwind_merge)
    assert isinstance(tailwind_merge(""), str)
    assert isinstance(tailwind_merge("hello world"), str)
    assert isinstance(tailwind_merge("-:-:-:::---h-"), str)
    assert isinstance(tailwind_merge("hello world", "-:-:-:::---h-"), str)
    assert isinstance(
        tailwind_merge("hello world", "-:-:-:::---h-", "", "something"), str
    )
    assert isinstance(tailwind_merge("hello world", None), str)
    assert isinstance(tailwind_merge("hello world", None, None), str)
    assert isinstance(tailwind_merge("hello world", None, None, False), str)
    assert isinstance(tailwind_merge("hello world", [None], [None, False]), str)
    assert isinstance(
        tailwind_merge("hello world", [None], [None, [False, "some-class"], []]), str
    )


def test_validators_have_correct_inputs_and_outputs():
    assert isinstance(validators.is_fraction(""), bool)
    assert isinstance(validators.is_arbitrary_length(""), bool)
    assert isinstance(validators.is_integer(""), bool)
    assert isinstance(validators.is_arbitrary_value(""), bool)
    assert isinstance(validators.is_arbitrary_variable(""), bool)
    assert isinstance(validators.is_any(""), bool)
    assert isinstance(validators.is_tshirt_size(""), bool)
    assert isinstance(validators.is_arbitrary_size(""), bool)
    assert isinstance(validators.is_arbitrary_position(""), bool)
    assert isinstance(validators.is_arbitrary_image(""), bool)
    assert isinstance(validators.is_arbitrary_number(""), bool)
    assert isinstance(validators.is_arbitrary_shadow(""), bool)


def test_mergeconfigs_has_correct_inputs_and_outputs():
    result = merge_configs(
        {
            "cache_size": 50,
            "theme": {},
            "class_groups": {
                "fooKey": [{"fooKey": ["one", "two"]}],
                "bla": [{"bli": ["blub", "blublub"]}],
            },
            "conflicting_class_groups": {},
            "conflicting_class_group_modifiers": {},
            "order_sensitive_modifiers": [],
        },
        {},
    )
    assert isinstance(result, dict)


def test_extendtailwindmerge_has_correct_inputs_and_outputs():
    assert callable(extend_tailwind_merge({}))


def test_fromtheme_has_correct_inputs_and_outputs():
    assert callable(from_theme("spacing"))

    theme_getter = from_theme("foo")
    assert callable(theme_getter)
    assert getattr(theme_getter, "is_theme_getter", False) is True
    assert theme_getter({"foo": ["hello"]}) == ["hello"]


def test_twjoin_has_correct_inputs_and_outputs():
    assert isinstance(tw_join(), str)
    assert isinstance(tw_join(""), str)
    assert isinstance(tw_join("", [False, None, None, 0, [], [False, [""], ""]]), str)
