from dataclasses import dataclass
from typing import Literal

@dataclass(frozen=True)
class NodeSelector:
    kind: Literal["one", "all", "tag", "subset"]
    nodeId: str | None = None
    tag: str | None = None
    nodeIds: set[str] | None = None

    @staticmethod
    def one(nodeId: str) -> "NodeSelector":
        return NodeSelector(kind="one", nodeId=nodeId)

    @staticmethod
    def all() -> "NodeSelector":
        return NodeSelector(kind="all")

    @staticmethod
    def byTag(tag: str) -> "NodeSelector":
        return NodeSelector(kind="tag", tag=tag)

    @staticmethod
    def subset(nodeIds: set[str]) -> "NodeSelector":
        return NodeSelector(kind="subset", nodeIds=nodeIds)
