"""$URL: svn+ssh://svn/repos/trunk/dulcinea/lib/contact.py $
$Id: contact.py 25629 2004-11-17 17:54:48Z nascheme $
"""

from dulcinea import local
from dulcinea.address import Addressable, ContactAddress
from dulcinea.base import DulcineaPersistent
from dulcinea.history import Historical
from dulcinea.permission import PermissionManager
from dulcinea.user import DulcineaUser, DulcineaUserDatabase
from dulcinea.typeutils import typecheck

class Contact(DulcineaUser, Addressable, Historical):
    """
    A more heavyweight user object that contains an Address object.
    Expects on a PermissionManager to determine if the user has admin power.

    Instance attributes:
      email : string
        the user's Internet email address
      prefix : string
      first_name : string
      last_name : string
      phone : string
      fax : string                  
      company_name : string
    """

    def __init__(self, user_id=None):
        DulcineaUser.__init__(self, user_id=user_id)
        Addressable.__init__(self)
        Historical.__init__(self)
        self.email = None
        self.prefix = None
        self.first_name = None
        self.last_name = None
        self.company_name = None
        self.phone = None
        self.fax = None

    def get_contact_address(self):
        address = self.get_address()
        return ContactAddress(
            contact_name=self.get_contact_name(),
            contact_phone_number = self.get_phone(),
            company_name=self.get_company_name(),
            **address.__dict__)

    def get_contact_name(self, limit=35):
        last_name = self.last_name or ''
        first_name = self.first_name
        contact_name = last_name
        if first_name and len(contact_name) <= limit:
            if limit - len(contact_name) > len(first_name) + 1:
                contact_name = first_name + ' ' + last_name
            elif limit - len(contact_name) > 2:
                contact_name = first_name[0] + ' ' + last_name
        return contact_name[:limit]

    def get_company_name(self):
        return self.company_name

    def set_company_name(self, company_name):
        typecheck(company_name, str, allow_none=1)
        self.company_name = company_name

    def format_realname(self):
        first_name = self.first_name or ''
        last_name = self.last_name or ''
        if first_name and last_name:
            return first_name + ' ' + last_name
        else:
            return first_name or last_name

    def format(self):
        """() -> string

        Return a string representing this user: either their real name
        (as returned by 'format_realname()') or their user ID.
        Guaranteed to return a non-empty string.
        """
        return self.format_realname() or self.id

    def set_prefix(self, prefix):
        typecheck(prefix, str, allow_none=True)
        self.prefix = prefix

    def get_prefix(self):
        return self.prefix

    def set_first_name(self, first_name):
        typecheck(first_name, str, allow_none=True)
        self.first_name = first_name

    def get_first_name(self):
        return self.first_name

    def set_last_name(self, last_name):
        typecheck(last_name, str, allow_none=True)
        self.last_name = last_name

    def get_last_name(self):
        return self.last_name

    def set_email(self, email):
        typecheck(email, str, allow_none=True)
        self.email = email

    def get_email(self):
        return self.email

    def set_phone(self, phone):
        typecheck(phone, str, allow_none=True)
        self.phone = phone

    def get_phone(self):
        return self.phone

    def set_fax(self, fax):
        typecheck(fax, str, allow_none=True)
        self.fax = fax

    def get_fax(self):
        return self.fax

    def get_email(self):
        return self.email

    def is_admin(self):
        return local.get_user_db().get_admin().directly_grants(
            'staff', self)

    def record_registration (self, host):
        self.history.add_event(None, 'register',
                               'new user ID registered from host %s' % host)

    def record_login (self, host):
        self.history.add_event(None, 'login', 'login from host %s' % host)

    def record_logout (self, host):
        self.history.add_event(None, 'logout', 'logout from host %s' % host)

    def record_failed_login (self, host):
        self.history.add_event(None, 'failed_login',
                               'failed login attempt from host %s' % host)

    def record_change (self, user, host, msg=None, password=0):
        code = password and 'change_password' or 'change'
        if msg is None:
            if password:
                msg = 'changed password'
            else:
                msg = 'changed other data'
        self.history.add_event(user, code, msg + ' (host %s)' % host)

    def record_act_as_start (self, user):
        self.history.add_event(user, 'act_as_start',
                               'Actual user %s began acting '
                               'as this user' % user.id)

    def get_registration_time (self):
        """() -> datetime | None
        """
        return self.history.find_last_date('register')

    def get_last_login_time (self):
        """() -> datetime | None"""
        return self.history.find_last_date('login')


class ContactAdmin(DulcineaPersistent, PermissionManager):
    """
    Instance attributes: none
    """
    valid_permissions = {
        "manage-permissions":
            "Allow changing of permissions.",
        "staff":
            ("Is a member of the staff, with all of the privileges and "
             "responsibilities thereunto appertaining."),
        "act-as":
            "Allow to act as another user.",
        "system":
            "Allow to do things normally done by the software system.",
        "create-users":
            "Allow the creation of other users."
        }

    def __init__(self):
        PermissionManager.__init__(self)

    def __str__(self):
        return 'admin'



class ContactDatabase(DulcineaUserDatabase):
    """
    Instance attributes:
      admin: ContactAdmin
      users : PersistentDict { user_id:string : user:Contact }
    """

    user_class = Contact

    def __init__(self, admin=None):
        DulcineaUserDatabase.__init__(self)
        system_user = self.user_class("SYSTEM")
        self.add_user(system_user)
        self.admin = admin or ContactAdmin()
        self.admin.set_permission('system', system_user)

    def get_admin(self):
        return self.admin
