from typing import Set
from dataclasses import dataclass
from itertools import product


@dataclass(frozen=True, eq=True)
class UserOption:  # 1
    nickname: str
    hobby: str
    email: str


def to_user_options(raw_user: dict) -> Set[UserOption]:
    return {
        UserOption(nickname=nickname, hobby=hobby, email=email)
        for nickname, hobby, email in product(  # 2
            raw_user["nicknames"], raw_user["hobbies"], raw_user["emails"]
        )
    }


def test_converts_to_all_options():
    user_input = {
        "name": "Alice",
        "nicknames": ["alice", "alison"],
        "emails": ["alice@in.wonder.land", "alice@knows.math"],
        "hobbies": ["climbing", "running", "acrobatics"],
    }  # 3

    actual_options = to_user_options(user_input)

    expected_options = {
        UserOption(nickname="alice", email="alice@in.wonder.land", hobby="climbing"),
        UserOption(nickname="alice", email="alice@in.wonder.land", hobby="running"),
        UserOption(nickname="alice", email="alice@in.wonder.land", hobby="acrobatics"),
        UserOption(nickname="alice", email="alice@knows.math", hobby="climbing"),
        UserOption(nickname="alice", email="alice@knows.math", hobby="running"),
        UserOption(nickname="alice", email="alice@knows.math", hobby="acrobatics"),
        UserOption(nickname="alison", email="alice@in.wonder.land", hobby="climbing"),
        UserOption(nickname="alison", email="alice@in.wonder.land", hobby="running"),
        UserOption(nickname="alison", email="alice@in.wonder.land", hobby="acrobatics"),
        UserOption(nickname="alison", email="alice@knows.math", hobby="climbing"),
        UserOption(nickname="alison", email="alice@knows.math", hobby="running"),
        UserOption(nickname="alison", email="alice@knows.math", hobby="acrobatics"),
    }

    assert actual_options == expected_options  # 4