# Path: crowd_anki/anki/adapters/anki_deck.py
# class AnkiDeck:
#     _data: dict
# 
#     deck_name_separator = '::'
# 
#     @property
#     def data(self):
#         return self._data
# 
#     @property
#     def is_dynamic(self):
#         return bool(self.data['dyn'])
# 
#     @property
#     def name(self):
#         return self.data['name']
# 
# Path: crowd_anki/anki/adapters/deck_manager.py
# class AnkiStaticDeckManager(DeckManager):
#     internal_deck_manager: Any
# 
#     def all(self) -> Iterable[AnkiDeck]:
#         return seq(self.internal_deck_manager.all()) \
#             .map(lambda d: AnkiDeck(d)) \
#             .filter(lambda d: not d.is_dynamic) \
#             .to_list()
# 
#     def leaf_decks(self, overrides: Iterable[AnkiDeck] = tuple()) -> Iterable[AnkiDeck]:
#         deck_trie = self.deck_trie()
#         override_keys = [deck.name for deck in overrides]
# 
#         remove_children_of(deck_trie, override_keys)
#         keys = keys_without_children(deck_trie)
# 
#         return [deck_trie[key] for key in keys]
# 
#     def deck_trie(self):
#         return StringTrie(**self.decks_by_name(), separator=AnkiDeck.deck_name_separator)
# 
#     def for_names(self, names: Iterable[str]):
#         """
#         The returned decks are lazy initialized with the actual internal content.
#         """
#         return [NamedLazyDeck(name, lambda name: self.internal_deck_manager.byName)
#                 for name in names]


from expects import expect, contain_only, equal
from mamba import description, it, before
from typing import Iterable
from unittest.mock import MagicMock
from crowd_anki.anki.adapters.anki_deck import AnkiDeck
from crowd_anki.anki.adapters.deck_manager import AnkiStaticDeckManager

internal_deck_names = ['a1::a2', 'b1', 'd1', 'a1']
override_deck_names = ['a1::a2', 'b1']
non_overridden_decks = ['c1', 'd1::d2']
leaf_deck_names = ['a1::a2::a3', 'b1::b2'] + non_overridden_decks


def deck_for_name(name):
    return AnkiDeck({'name': name, 'dyn': False})


def dummy_deck_for_names(names):
    return [deck_for_name(name) for name in names]


def data_from_decks(decks: Iterable[AnkiDeck]):
    return [deck.data for deck in decks]


internal_decks = dummy_deck_for_names(internal_deck_names)
leaf_decks = dummy_deck_for_names(leaf_deck_names)
override_decks = dummy_deck_for_names(override_deck_names)

with description(AnkiStaticDeckManager) as self:
    def mock_internal_manager(self, decks):
        self.internal_manager.all.return_value = data_from_decks(decks)


    with before.each:
        self.internal_manager = MagicMock()

# Path: crowd_anki/anki/adapters/anki_deck.py
# class AnkiDeck:
#     _data: dict
# 
#     deck_name_separator = '::'
# 
#     @property
#     def data(self):
#         return self._data
# 
#     @property
#     def is_dynamic(self):
#         return bool(self.data['dyn'])
# 
#     @property
#     def name(self):
#         return self.data['name']
# 
# Path: crowd_anki/anki/adapters/deck_manager.py
# class AnkiStaticDeckManager(DeckManager):
#     internal_deck_manager: Any
# 
#     def all(self) -> Iterable[AnkiDeck]:
#         return seq(self.internal_deck_manager.all()) \
#             .map(lambda d: AnkiDeck(d)) \
#             .filter(lambda d: not d.is_dynamic) \
#             .to_list()
# 
#     def leaf_decks(self, overrides: Iterable[AnkiDeck] = tuple()) -> Iterable[AnkiDeck]:
#         deck_trie = self.deck_trie()
#         override_keys = [deck.name for deck in overrides]
# 
#         remove_children_of(deck_trie, override_keys)
#         keys = keys_without_children(deck_trie)
# 
#         return [deck_trie[key] for key in keys]
# 
#     def deck_trie(self):
#         return StringTrie(**self.decks_by_name(), separator=AnkiDeck.deck_name_separator)
# 
#     def for_names(self, names: Iterable[str]):
#         """
#         The returned decks are lazy initialized with the actual internal content.
#         """
#         return [NamedLazyDeck(name, lambda name: self.internal_deck_manager.byName)
#                 for name in names]


# Path: test/anki/adapters/deck_manager_spec.py
from expects import expect, contain_only, equal
from mamba import description, it, before
from typing import Iterable
from unittest.mock import MagicMock
from crowd_anki.anki.adapters.anki_deck import AnkiDeck
from crowd_anki.anki.adapters.deck_manager import AnkiStaticDeckManager


internal_deck_names = ['a1::a2', 'b1', 'd1', 'a1']
override_deck_names = ['a1::a2', 'b1']
non_overridden_decks = ['c1', 'd1::d2']
leaf_deck_names = ['a1::a2::a3', 'b1::b2'] + non_overridden_decks


def deck_for_name(name):
    return AnkiDeck({'name': name, 'dyn': False})


def dummy_deck_for_names(names):
    return [deck_for_name(name) for name in names]


def data_from_decks(decks: Iterable[AnkiDeck]):
    return [deck.data for deck in decks]


internal_decks = dummy_deck_for_names(internal_deck_names)
leaf_decks = dummy_deck_for_names(leaf_deck_names)
override_decks = dummy_deck_for_names(override_deck_names)

with description(AnkiStaticDeckManager) as self:
    def mock_internal_manager(self, decks):
        self.internal_manager.all.return_value = data_from_decks(decks)


    with before.each:
        self.internal_manager = MagicMock()

        self.static_deck_manager = AnkiStaticDeckManager(self.internal_manager)