#!/usr/bin/env python

import argparse, sys

from types import FileType
from clas_conf import *
from aliases.alias import AliasAdd, AliasDelete, AliasModify
from tools.misc import check_email

ACTION = (
    'add',
    'delete',
    'modify'
    )

def parse_args():
    class MailAction(argparse.Action):
        HELP = "Parameter EMAIL can have two forms: `user' or " + \
               "`user@domain.example'. In the first case, parameter EMAIL " + \
               "is rewritten `user@ENTITY_TO_MAIL['entity'].%s'. " % DOMAIN + \
               "For example, if entity is `system', `admin' is rewritten " + \
               "`admin@%s.%s" % (ENTITY_TO_MAIL['system'], DOMAIN)
        
        def __call__(self, parser, namespace, values, option_string=None):
            if '@' not in values[0]:
               values[0] += '@%s.%s' % \
                            (ENTITY_TO_MAIL[namespace.entity], DOMAIN)
            if option_string in ('-A', '--mailalias'):
                setattr(namespace, self.dest, values[0])
            else:
                val = getattr(namespace, self.dest)
                if val is None:
                    val = values
                else:
                    val += values
                setattr(namespace, self.dest, val)

    class FileAction(argparse.Action):
        HELP = 'FILE is a file containing a list of members of mail alias.' + \
               ' FILE format is simple: one email member per line. Note ' + \
               "that options `-f' and `-m' are mutually exclusive"
        
        def __call__(self, parser, namespace, values, option_string=None):
            try:
                fd = open(values[0], 'r')
            except IOError, msg:
                 parser.exit(
                    1, "%s: option %s: can't open `%s': %s\n" %
                    (parser.prog, option_string, values[0], msg)
                    )
            setattr(namespace, 'mail', fd)

    parser = argparse.ArgumentParser(
        description='manage mail aliases on %s' % SERVER
        )
    subparsers = parser.add_subparsers(
        title='subcommands', help='list of valid subcommands', dest='sub_cmd'
        )
    sp = []
    for a in ACTION:
        p = subparsers.add_parser(a, help=a + ' a mail alias')
        sp.append((p, a))
    for p in sp:
        p[0].add_argument(
            '-e', '--entity', choices=ENTITIES, required=True,
            help='entity (LDAP field: departmentNumber)'
            )
        p[0].add_argument(
            '-A', '--mailalias', nargs=1, required=True, action=MailAction,
            metavar='EMAIL', help='mail alias. ' + MailAction.HELP
            )
        if p[1] == 'add':
            group = p[0].add_mutually_exclusive_group(required=True)
            group.add_argument(
                '-f', '--file', nargs=1, action=FileAction, help=FileAction.HELP
                )
            group.add_argument(
                '-m', '--mail', nargs=1, metavar='EMAIL', action=MailAction,
                help="email of a member of mail alias. See option `-A' for " +
                'parameter EMAIL syntax. ' +
                "Option `-m' can appear multiple times in command line. " +
                "Note that options `-f' and `-m' are mutually exclusive"
                )
            p[0].add_argument(
                '--mailenable', choices=('yes', 'no'), default='yes',
                help="LDAP field: mailenable. Default is `yes'"
                )
        elif p[1] == 'modify':
            p[0].add_argument(
                '-a', '--add', nargs=1, metavar='EMAIL', action=MailAction,
                default=[],
                help='email of a member to add to mail alias. ' +
                "Option `-a' can appear multiple times in command line. " +
                "See option `-A' for parameter EMAIL syntax."
                )
            p[0].add_argument(
                '-d', '--delete', nargs=1, metavar='EMAIL', action=MailAction,
                default=[],
                help='email of a member to remove from mail alias. ' +
                "Option `-d' can appear multiple times in command line. " +
                "See option `-A' for parameter EMAIL syntax."
                )
    args = parser.parse_args()
    if args.sub_cmd == 'modify' and not args.add and not args.delete:
        parser.error("at least one option `-a' or `-d' must be present")
    if hasattr(args, 'file'):
        delattr(args, 'file')
    return args

def main():
    args = parse_args()
    sub_cmd = args.sub_cmd
    delattr(args, 'sub_cmd')
    try:
        exec('Alias%s(**vars(args))' % sub_cmd.capitalize())
        print "`%s %s' succeeded" % (sys.argv[0], sub_cmd)
    except Exception, msg:
        print "`%s %s' failed: %s" % (sys.argv[0], sub_cmd, msg)
    finally:
        if hasattr(args, 'mail') and type(args.mail) is FileType:
            args.mail.close()

if __name__ == '__main__':
    main()
