#
# SchoolTool - common information systems platform for school administration
# Copyright (c) 2012 Shuttleworth Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
"""
SchoolTool LDAP interfaces
"""

import zope.schema
from zope.interface import Interface

from schooltool.ldap import SchoolToolLDAPMessage as _


class ILDAPConfig(Interface):

    uri = zope.schema.TextLine(
        title=_('LDAP server URI'),
        description=_('Example: ldap://localhost:389'),
        required=False,
        )

    bind_dn = zope.schema.TextLine(
        title=_('Bind DN'),
        description=_(
            'LDAP distinguished name to bind for searching '
            'users to authenticate.'
        ),
        default=u"",
        required=False)

    bind_password = zope.schema.Password(
        title=_('Bind password'),
        description=_('Bind DN password.'),
        default=u"",
        required=False)

    timeout = zope.schema.Int(
        title=_('Timeout (in seconds).'),
        required=False,
        )


class ILDAPPersonsConfig(ILDAPConfig):

    queries = zope.schema.Text(
        title=_("User DN queries"),
        description=_(
            'One or more queries to obtain LDAP users, in form of '
            '"login_attribute base?scope?filter" (scope is base/one/sub). '
            'Examples: '
            '"uid   ou=Users,dc=localhost?sub?(objectClass=inetOrgPerson)", '
            '"cn   ou=Users,dc=school,dc=example,dc=com?one?(objectClass=person)"'
        ),
        required=False)

    groupQueries = zope.schema.Text(
        title=_("Group DN queries"),
        description=_(
            'One or more queries to obtain LDAP groups, in form of '
            '"login_attribute base?scope?filter" (scope is base/one/sub). '
            'Examples: '
            '"dc=localhost?sub?(objectClass=posixGroup)", '
            '"ou=Groups,dc=school,dc=example,dc=com?one"'
        ),
        required=False)

    posixGroups = zope.schema.Text(
        title=_("POSIX group counterparts in SchoolTool."),
        description=_(
            '"School year" (optional) "Group ID" "POSIX group ID". '
            'Examples: '
            '"2011-2012, teachers, 6001", '
            '"2012-2013, teachers, 7001", '
            '", students, 6000"'
        ),
        required=False)


class ILDAPAutoConfig(ILDAPPersonsConfig):

    enable_ttw = zope.schema.Bool(
        title=_("Enable TTW editing"),
        required=False)


class ILDAPClient(ILDAPConfig):

    uri = zope.schema.TextLine(
        title=_('LDAP server URI'),
        description=_('Example: ldap://localhost:389'),
        required=False,
        )

    configured = zope.schema.Bool(
        title=_('Configured'),
        description=_('Is this client properly configured.'),
        required=False,
        )

    def connect(dn=None, password=None):
        """Connect to LDAP (and optionally bind to DN/password)."""

    def search(query, scope=None, filter=None, **kw):
        """
        Query the LDAP server.
        Query syntax: "base?scope?filter", where scope is "base"/"one"/"sub".
        "scope" can be specified to override the query.
        "filter" can be specified as dict or properly formatted filter string.

        Other keywords will be passed to ldap.LDAPObject.search_ext_s
        """

    def close():
        """Close the connection."""

    def ping(uri=None):
        """Ping the LDAP server at given URI (or self.uri if None is passed)."""


class ILDAPPersonsClient(ILDAPClient, ILDAPPersonsConfig):

    queries = zope.schema.List(
        title=_("User DN queries"),
        value_type=zope.schema.List(
            title=_("login_attribute, query"),
            value_type=zope.schema.Text(title=u"Entry"))
        )

    groupQueries = zope.schema.List(
        title=_("Group DN queries"),
        value_type=zope.schema.Text(title=u"Entry"),
        )

    posixGroups = zope.schema.List(
        title=_("POSIX group counterparts."),
        value_type=zope.schema.List(
            title=_("Year ID, group ID, posix ID"),
            value_type=zope.schema.Text(title=u"Entry"))
        )

    def login(username, password):
        """Bind as username/password"""

    def __iter__():
        """Iterate LDAP users from all queries."""


class ISchoolToolLDAPObjectPart(Interface):

    def update():
        """Update the target with info provided by this LDAP class."""


class ISchoolToolLDAPObject(Interface):

    def update():
        """Update the object with information from LDAP."""
