# -*- coding: utf-8 -*-

"""
The postman project - models.py

This file is released under the BSD license, see LICENSE for
more information.

Francisco de Borja Lopez Rio - <borja@codigo23.net>
Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
"""

import os
from tools import validate_email_address
from storage import JsonStorage as Storage
import config

class Member():

    """
    Class that defines a mailing list member
    """

    def __init__(self, address):
        self.address = self._validate_address(address)
        
    def __repr__(self):
        return "<Member '%s'>" % self.address

    def __str__(self):
        return self.address

    def _validate_address(self, address):
        if not validate_email_address(address):
            raise ValueError(address, ' is not a valid email address')
        return address


class MailingList():

    """
    Class that defines a mailing list
    """

    def __init__(self, name, address, members={}, configfile=None):
        self.configfile = configfile
        self.storage_config = config.get_config_parameters('storage',
                                                           configfile)
        self.archive_config = config.get_config_parameters('archive',
                                                           configfile)
        self.mailing_config = config.get_config_parameters('mailing_lists',
                                                           configfile)
        self.name = name
        self.address = address
        self.members = members
        
    def __repr__(self):
        return "<MailingList '%s'>" % self.address

    def __str__(self):
        return self.address
        
    def _validate_member_object(self, member=None):
        if not isinstance(member, Member):
            raise TypeError(member, ' is not a valid Member instance')
        return member

    def _validate_member(self, member=None):
        member = self._validate_member_object(member)
        return member.address in self.members_addresses()

    def _validate_member_by_address(self, address=None):
        if not validate_email_address(address):
            raise ValueError(address, ' is not a valid email address')
        return address in self.members_addresses()

    @property
    def storage(self):
        return Storage(os.path.join(self.storage_config['path'], self.address))

    @property
    def archive(self):
        return Storage(os.path.join(self.archive_config['path'], self.address))
    
    def members_addresses(self):
        return self.members.keys()

    def add_member(self, member):
        member = self._validate_member_object(member)
        if self._validate_member(member):
            return False
        self.members[member.address] = member
        return True

    def add_member_by_address(self, address=None):
        if self._validate_member_by_address(address):
            return False
        member = Member(address)
        self.members[address] = member
        return True
                
    def delete_member(self, member=None):
        member = self._validate_member_object(member)
        if not self._validate_member(member):
            return False
        del self.members[member.address]
        return True

    def info(self):
        """
        Returns a dict we can use to add this mailing list to a postman
        instance
        """
        # FIXME: This code could be replaced with something that
        # automagically generates the dict from the instance attributes
        return {'name': self.name, 'address': self.address,
                'members': self.members, 'configfile': self.configfile}

    def load(self):
        if self.storage.exists():
            data = self.storage.read()
            self.name = data.name
            self.address = data.address
            self.members = data.members
            return True
        return False
    
    def save(self):
        self.storage.write(self)
