from Acquisition import aq_base
from plone.app.vocabularies.catalog import CatalogSource
from plone.autoform.interfaces import IFormFieldProvider
from plone.supermodel import model
from ploneintranet.core import _
from ploneintranet.workspace.superspace import ISuperspaceFolder
from z3c.relationfield.schema import RelationChoice
from zope.interface import provider


# a schema constraint can not detect wheteher a loop would be created, because
# it does not know the object that value will be assigned to! This only checks
# whether value is part of an existing loop
def checkForLoop(value):
    if not value.superspace:
        return True
    if not getattr(aq_base(value.superspace), "to_object", False):
        return False
    path = [value]
    current = value.superspace.to_object
    while current:
        if current in path:
            return False
        if not current.superspace:
            return True
        path.append(current)
        current = current.superspace.to_object
    return True


@provider(IFormFieldProvider)
class ISubspace(model.Schema):
    """Behavior used for both SuperSpaces and Subspaces"""

    superspace = RelationChoice(
        title=_("Superspace"),
        default=None,
        source=CatalogSource(object_provides=[ISuperspaceFolder.__identifier__]),
        constraint=checkForLoop,
        required=False,
    )
