from optparse import make_option

from django.contrib.auth.models import User, Group
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction

from docbow_project.docbow.models import MailingList, DocbowProfile


def get_object(model, ref):
    '''Try to get a model by id or by name'''
    if ref.isdigit():
        return model.objects.get(id=int(ref))
    else:
        return model.objects.get(name=ref)

class Command(BaseCommand):
    args = '<username>'
    help = '''Create a new user or update an existing user

List and groups can be referred by name or by id.
    '''

    option_list = BaseCommand.option_list + (
            make_option("--first-name", help='set first name'),
            make_option("--last-name", help='set last name'),
            make_option("--email", help='set email'),
            make_option("--mobile-phone",
                help='set mobile phone used for SMS notifications'),
            make_option("--personal-email", help='set personal email'),
            make_option("--add-list",
                help='add user to list', action="append", default=[]),
            make_option("--add-group",
                help='add user to group', action="append", default=[]),
            make_option("--remove-list",
                help='remove user from list', action="append", default=[]),
            make_option("--remove-group",
                help='remove user from group', action="append", default=[]),
            make_option("--activate", action="store_true",
                help='activate the user (default at creation)', default=None),
            make_option("--deactivate", dest='activate', action="store_false",
                help='deactivate the user'),
            make_option("--superuser", action="store_true",
                help='set the superuser flag', default=None),
            make_option("--no-superuser", dest='superuser',
                action="store_false", help='unset the superuser flag'),
    )


    @transaction.commit_on_success
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError('username argument is mandatory')
        user, created = User.objects.get_or_create(username=args[0])
        if options['first_name']:
            user.first_name = options['first_name'].decode('utf-8')
        if options['last_name']:
            user.last_name = options['last_name'].decode('utf-8')
        if options['email']:
            user.email = options['email'].decode('utf-8')
        if options['activate'] is not None:
            user.is_active = options['activate']
        if options['superuser'] is not None:
            user.is_superuser = options['superuser']
        try:
            for l in options['add_list']:
                l = get_object(MailingList, l)
                l.members.add(user)
            for l in options['remove_list']:
                l = get_object(MailingList, l)
                l.members.remove(user)
        except MailingList.DoesNotExist:
             raise CommandError('list %r does not exist' % l)
        try:
            for g in options['add_group']:
                g = get_object(Group, g)
                user.groups.add(g)
            for g in options['remove_group']:
                g = get_object(Group, g)
                user.groups.remove(g)
        except Group.DoesNotExist:
            raise CommandError('group %r does not exist' % g)
        profile, created = DocbowProfile.objects.get_or_create(user=user)
        if options['mobile_phone']:
            profile.mobile_phone = options['mobile_phone'].decode('utf-8')
        if options['personal_email']:
            profile.personal_email = options['personal_email'].decode('utf-8')
        user.save()
        profile.save()
