import weakref

from typing import List
from pxr import Sdf, Usd


class PrimSelectionPayload:
    def __init__(self, stage: weakref.ReferenceType(Usd.Stage), paths: List[Sdf.Path]):
        self._stage = stage  # weakref
        self._payload = paths
        self._ignore_large_selection_override = False

        import omni.kit.property.usd
        self._large_selection_count = omni.kit.property.usd.get_large_selection_count()

    def __len__(self):
        # Ignore payload if stage is not valid anymore
        if self._stage is None or self._stage() is None:
            return 0

        return len(self._payload)

    # Forward calls to list to keep backward compatibility/easy access
    def __iter__(self):
        return self._payload.__iter__()

    def __getitem__(self, key):
        return self._payload.__getitem__(key)

    def __setitem__(self, key, value):
        return self._payload.__setitem__(key, value)

    def __delitem__(self, key):
        return self._payload.__delitem__(key)

    def __bool__(self):
        return self._stage is not None and self._stage() is not None and len(self._payload) > 0

    def get_stage(self):
        return self._stage() if self._stage else None  # weakref -> ref

    def get_paths(self) -> List[Sdf.Path]:
        return self._payload

    def set_large_selection_override(self, state: bool):
        self._ignore_large_selection_override = state

    def get_large_selection_count(self):
        return self._large_selection_count

    def is_large_selection(self) -> bool:
        if not self._ignore_large_selection_override:
            return bool(self._large_selection_count and len(self._payload) > self._large_selection_count)
        return False
