# SPDX-License-Identifier: MIT
from __future__ import annotations

import pytest
from hypothesis import given
from hypothesis import strategies as st

from xattrs.converters import (
    to_camel,
    to_const,
    to_kebab,
    to_pascal,
    to_secret,
    to_snake,
)

SNAKE_CASES = ["foo", "foo_bar", "foo_bar_baz"]
KEBAB_CASES = ["foo", "foo-bar", "foo-bar-baz"]
CAMEL_CASES = ["foo", "fooBar", "fooBarBaz"]
PASCAL_CASES = ["Foo", "FooBar", "FooBarBaz"]
CONST_CASES = ["FOO", "FOO_BAR", "FOO_BAR_BAZ"]


@pytest.fixture(scope="module")
def snake_cases():
    return set(SNAKE_CASES)


@pytest.fixture(scope="module")
def kebab_cases():
    return set(KEBAB_CASES)


@pytest.fixture(scope="module")
def const_cases():
    return set(CONST_CASES)


@pytest.fixture(scope="module")
def camel_cases():
    return set(CAMEL_CASES)


@pytest.fixture(scope="module")
def pascal_cases():
    return set(PASCAL_CASES)


class TestStringConverters:
    @given(
        kebal=st.sampled_from(KEBAB_CASES + CONST_CASES + CAMEL_CASES + PASCAL_CASES)
    )
    def test_to_snake(self, kebal, snake_cases):
        assert to_snake(kebal) in snake_cases

    @given(
        value=st.sampled_from(SNAKE_CASES + CONST_CASES + CAMEL_CASES + PASCAL_CASES)
    )
    def test_to_kebab(self, value, kebab_cases):
        assert to_kebab(value) in kebab_cases

    @given(
        value=st.sampled_from(SNAKE_CASES + KEBAB_CASES + CAMEL_CASES + PASCAL_CASES)
    )
    def test_to_const(self, value, const_cases):
        assert to_const(value) in const_cases

    # FIXME: failed for CONST_CASES
    @given(value=st.sampled_from(SNAKE_CASES + KEBAB_CASES + PASCAL_CASES))
    def test_to_camel(self, value, camel_cases):
        assert to_camel(value) in camel_cases

    # FIXME: failed for CONST_CASES
    @given(value=st.sampled_from(SNAKE_CASES + KEBAB_CASES + CAMEL_CASES))
    def test_to_pascal(self, value, pascal_cases):
        assert to_pascal(value) in pascal_cases


@pytest.mark.parametrize(
    ("value", "expected", "extra"),
    [
        ("foo", "******", {}),
        ("foo------bar", "######", {"marker": "#"}),
        ("asdfasdfadfbar", "###", {"marker": "#", "length": 3}),
        ("asdfasdfadfbar", "**************", {"length": None}),
    ],
)
def test_to_secret(value, expected, extra):
    assert to_secret(value, **extra) == expected
