# Path: siebenapp/domain.py
# class Select(Command):
#     """Select a goal by its id whether it exist. Do nothing in other case"""
# 
#     goal_id: int
# 
# class ToggleClose(Command):
#     """Close an open selected goal. Re-open a closed selected goal"""
# 
#     root: int = 0
# 
# class EdgeType(IntEnum):
#     BLOCKER = 1
#     PARENT = 2
# 
# class HoldSelect(Command):
#     """Saves current selection into the "previous selection" state"""
# 
# Path: siebenapp/open_view.py
# class ToggleOpenView(Command):
#     """Switch between "only open goals" and "all goals" views"""
# 
# class OpenView(Graph):
#     """Non-persistent view layer that allows to switch
#     between only-open (plus selected) and all goals"""
# 
#     def __init__(self, goaltree: Graph):
#         super().__init__(goaltree)
#         self._open: bool = True
# 
#     def accept_ToggleOpenView(self, command: ToggleOpenView):
#         self._open = not self._open
# 
#     def settings(self, key: str) -> Any:
#         if key == "filter_open":
#             return self._open
#         return self.goaltree.settings(key)
# 
#     def reconfigure_from(self, origin: "Graph") -> None:
#         super().reconfigure_from(origin)
#         if not origin.settings("filter_open"):
#             self.accept(ToggleOpenView())
# 
#     @with_key("open")
#     def q(self, keys: str = "name") -> Dict[int, Any]:
#         goals = self.goaltree.q(keys)
#         result: Dict[int, Any] = {
#             k: {}
#             for k, v in goals.items()
#             if not self._open or v["open"] or k in self.selections()
#         }
#         # goals without parents
#         not_linked: Set[int] = set(g for g in result.keys() if g > 1)
#         for goal_id in result:
#             val = goals[goal_id]
#             result[goal_id] = {k: v for k, v in val.items() if k != "edge"}
#             if "edge" in keys:
#                 filtered_edges: List[Tuple[int, EdgeType]] = []
#                 for edge in val["edge"]:
#                     if edge[0] in result:
#                         filtered_edges.append(edge)
#                         if edge[0] > 1:
#                             not_linked.discard(edge[0])
#                 result[goal_id]["edge"] = filtered_edges
#         if "edge" in keys:
#             # here we know something about other layers (Zoom). I do not like it
#             root_goals: Set[int] = set(result.keys()).intersection({1, -1})
#             if root_goals:
#                 root_goal: int = root_goals.pop()
#                 for missing_goal in not_linked:
#                     result[root_goal]["edge"].append((missing_goal, EdgeType.BLOCKER))
#         return result
# 
# Path: siebenapp/tests/dsl.py
# class GoalPrototype:
# def _build_goal_prototype(goal_id, name, is_open, children, blockers, select):
# def open_(goal_id, name, children=None, blockers=None, select=None):
# def clos_(goal_id, name, children=None, blockers=None, select=None):
# def build_goaltree(*goal_prototypes, message_fn=None):


import pytest
from siebenapp.domain import Select, ToggleClose, EdgeType, HoldSelect
from siebenapp.open_view import ToggleOpenView, OpenView
from siebenapp.tests.dsl import build_goaltree, open_, selected, clos_, previous
def test_closed_goal_is_shown_after_switch(two_goals):
    two_goals.accept(ToggleOpenView())
    assert two_goals.q("name,open,edge") == {
        1: {"name": "Open", "open": True, "edge": [(2, EdgeType.PARENT)]},
        2: {"name": "Closed", "open": False, "edge": []},
    }
    two_goals.accept(ToggleOpenView())
    assert two_goals.q("name,open,edge") == {
        1: {"name": "Open", "open": True, "edge": []}
    }


def test_simple_open_enumeration_workflow():
    e = OpenView(
        build_goaltree(
            open_(1, "Root", [2, 3], select=previous),
            open_(2, "1", select=selected),
            open_(3, "2"),
        )
    )
    assert e.q(keys="name,select,open,edge") == {
        1: {
            "name": "Root",
            "select": "prev",
            "open": True,
            "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)],
        },
        2: {"name": "1", "select": "select", "open": True, "edge": []},
        3: {"name": "2", "select": None, "open": True, "edge": []},
    }

# Path: siebenapp/domain.py
# class Select(Command):
#     """Select a goal by its id whether it exist. Do nothing in other case"""
# 
#     goal_id: int
# 
# class ToggleClose(Command):
#     """Close an open selected goal. Re-open a closed selected goal"""
# 
#     root: int = 0
# 
# class EdgeType(IntEnum):
#     BLOCKER = 1
#     PARENT = 2
# 
# class HoldSelect(Command):
#     """Saves current selection into the "previous selection" state"""
# 
# Path: siebenapp/open_view.py
# class ToggleOpenView(Command):
#     """Switch between "only open goals" and "all goals" views"""
# 
# class OpenView(Graph):
#     """Non-persistent view layer that allows to switch
#     between only-open (plus selected) and all goals"""
# 
#     def __init__(self, goaltree: Graph):
#         super().__init__(goaltree)
#         self._open: bool = True
# 
#     def accept_ToggleOpenView(self, command: ToggleOpenView):
#         self._open = not self._open
# 
#     def settings(self, key: str) -> Any:
#         if key == "filter_open":
#             return self._open
#         return self.goaltree.settings(key)
# 
#     def reconfigure_from(self, origin: "Graph") -> None:
#         super().reconfigure_from(origin)
#         if not origin.settings("filter_open"):
#             self.accept(ToggleOpenView())
# 
#     @with_key("open")
#     def q(self, keys: str = "name") -> Dict[int, Any]:
#         goals = self.goaltree.q(keys)
#         result: Dict[int, Any] = {
#             k: {}
#             for k, v in goals.items()
#             if not self._open or v["open"] or k in self.selections()
#         }
#         # goals without parents
#         not_linked: Set[int] = set(g for g in result.keys() if g > 1)
#         for goal_id in result:
#             val = goals[goal_id]
#             result[goal_id] = {k: v for k, v in val.items() if k != "edge"}
#             if "edge" in keys:
#                 filtered_edges: List[Tuple[int, EdgeType]] = []
#                 for edge in val["edge"]:
#                     if edge[0] in result:
#                         filtered_edges.append(edge)
#                         if edge[0] > 1:
#                             not_linked.discard(edge[0])
#                 result[goal_id]["edge"] = filtered_edges
#         if "edge" in keys:
#             # here we know something about other layers (Zoom). I do not like it
#             root_goals: Set[int] = set(result.keys()).intersection({1, -1})
#             if root_goals:
#                 root_goal: int = root_goals.pop()
#                 for missing_goal in not_linked:
#                     result[root_goal]["edge"].append((missing_goal, EdgeType.BLOCKER))
#         return result
# 
# Path: siebenapp/tests/dsl.py
# class GoalPrototype:
# def _build_goal_prototype(goal_id, name, is_open, children, blockers, select):
# def open_(goal_id, name, children=None, blockers=None, select=None):
# def clos_(goal_id, name, children=None, blockers=None, select=None):
# def build_goaltree(*goal_prototypes, message_fn=None):


# Path: siebenapp/tests/test_open_view.py
import pytest
from siebenapp.domain import Select, ToggleClose, EdgeType, HoldSelect
from siebenapp.open_view import ToggleOpenView, OpenView
from siebenapp.tests.dsl import build_goaltree, open_, selected, clos_, previous

def test_closed_goal_is_shown_after_switch(two_goals):
    two_goals.accept(ToggleOpenView())
    assert two_goals.q("name,open,edge") == {
        1: {"name": "Open", "open": True, "edge": [(2, EdgeType.PARENT)]},
        2: {"name": "Closed", "open": False, "edge": []},
    }
    two_goals.accept(ToggleOpenView())
    assert two_goals.q("name,open,edge") == {
        1: {"name": "Open", "open": True, "edge": []}
    }


def test_simple_open_enumeration_workflow():
    e = OpenView(
        build_goaltree(
            open_(1, "Root", [2, 3], select=previous),
            open_(2, "1", select=selected),
            open_(3, "2"),
        )
    )
    assert e.q(keys="name,select,open,edge") == {
        1: {
            "name": "Root",
            "select": "prev",
            "open": True,
            "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)],
        },
        2: {"name": "1", "select": "select", "open": True, "edge": []},
        3: {"name": "2", "select": None, "open": True, "edge": []},
    }

    e.accept(ToggleClose())