"""
$URL: svn+ssh://sting.mems-exchange.org/repos/trunk/DurusWorks/qp/mail/rfc822_mailbox.py $
$Id: rfc822_mailbox.py 33604 2011-03-13 15:07:01Z dbinger $
"""
from qp.lib.spec import string_classes
from qpy import stringify
import re
import sys
if sys.version < "3":
    from email.Header import Header, decode_header
    from email.Utils import parseaddr
else:
    from email.header import Header, decode_header
    from email.utils import parseaddr

rfc822_specials_re = re.compile(r'[\(\)\<\>\@\,\;\:\\\"\.\[\]]')

decode_header # quiet checker.

def encode_header(s):
    if s == '':
        s += '\n'
    return Header(stringify(s)).encode()

class RFC822Mailbox:
    """
    In RFC 822, a "mailbox" is either a bare e-mail address or a bare
    e-mail address coupled with a chunk of text, most often someone's
    name.  Eg. the following are all "mailboxes" in the RFC 822 grammar:
      luser@example.com
      Joe Luser <luser@example.com>
      Paddy O'Reilly <paddy@example.ie>
      "Smith, John" <smith@example.com>
      Dick & Jane <dickjane@example.net>
      "Tom, Dick, & Harry" <tdh@example.org>

    This class represents an (addr_spec, real_name) pair and takes care
    of quoting the real_name according to RFC 822's rules for you.
    Just use the format() method and it will spit out a properly-
    quoted RFC 822 "mailbox".
    """

    def __init__(self, addr_spec, real_name=''):
        self.real_name = stringify(real_name)
        parsed_real_name, self.addr_spec = parseaddr(addr_spec)
        if parsed_real_name:
            self.real_name = parsed_real_name

    def get_addr_spec(self):
        return self.addr_spec

    def get_real_name(self):
        return self.real_name

    def __eq__(self, other):
        return (isinstance(other, RFC822Mailbox) and
                self.get_addr_spec() == other.get_addr_spec() and
                self.get_real_name() == other.get_real_name())

    def format(self):
        encoded_real_name = encode_header(self.real_name)
        addr = str(self.addr_spec)
        if encoded_real_name and rfc822_specials_re.search(encoded_real_name):
            return '"%s" <%s>' % (encoded_real_name.replace('"', '\\"'),
                                  addr)
        elif encoded_real_name:
            return '%s <%s>' % (encoded_real_name, addr)

        else:
            return addr


def rfc822_mailbox(s):
    """(s:None|str|tuple|RFC822Mailbox) -> RFC822Mailbox | None
    Tries to make an RFC822Mailbox from the argument if it is a tuple or str.
    """
    if s is None:
        return s
    if isinstance(s, RFC822Mailbox):
        return s
    if type(s) is tuple:
        return RFC822Mailbox(*s)
    if isinstance(s, string_classes):
        return RFC822Mailbox(s, '')
    raise TypeError("expected None, 2-tuple, or str\ngot %r" % s)


