#!/usr/bin/env python
from __future__ import with_statement

import datetime
import optparse
import os
import pwd
import re
import readline
import subprocess
import sys

from email.mime.text import MIMEText

BASEDIR = os.path.dirname(__file__)
REQUIRED_LISTS = [{'name' : 'sipb-prospectives-%i' % datetime.datetime.now().year,
                   'description' : 'List of all non-keyholder SIPB members'}]
OPTIONAL_LISTS = [{'name' : 'rt-sipb-consultants',
                   'description' : 'Support list for random user questions.'},
                  {'name' : 'sipb-minutes',
                   'description' : 'Where the minutes taken at each meeting get sent'},
                  {'name' : 'sipb-soc',
                   'description' : 'The SIPB social list'},
                  {'name' : 'sipb-jobs',
                   'description' : 'Where people who are looking to hire you look'}]
OPTS = None
WELCOME_EMAIL = {'To' : '%(email)s',
                 'From' : 'The SIPB Chair <sipb-chair@mit.edu>',
                 'Bcc' : 'prospectivizations@mit.edu',
                 'Subject' : 'Welcome to SIPB!',
                 '__body__' :
"""So you've just become a SIPB member. Welcome to the SIPB 
community, %(username)s! We're excited that you've become interested in 
SIPB, and hope that you'll continue to hang out in our office and 
work with us to improve computing at MIT.

There's a lot going on at SIPB! This email 
is intended to give you pointers on how to get
involved in the SIPB community. If you have any questions, don't 
hesitate to hit that reply button.

== Useful Info ==

What does SIPB do? 

SIPB is MIT's first and oldest computing club, where student volunteers
can contribute to improving and maintaining MIT's computing infrastructure. It's
also a social and educational group, where people of all backgrounds come together
to talk and learn more about computing. 

How can I get involved? 

Hang around the office, help out with a project or start your own, 
volunteer at SIPB events, talk to other SIPB members on Mattermost 
(https://mattermost.xvm.mit.edu/signup_user_complete/?id=pnfpw5qkpjnxxrq319ynh94eke).

What does being a SIPB Keyholder mean? 

Keyholders are longtime members of SIPB, elected to have certain 
responsibilities and privileges, including:

- Ability to hold an officer position in the EC (Executive Committee)
- A vote at SIPB meetings (and, if a current student, in SIPB Elections)
- A key to the SIPB office (thus 'keyholder' - they hold the keys)
- A drawer in the SIPB office

How do I become a keyholder? 

The best way to become a keyholder is to be involved in SIPB! 
This means helping out in the office, working on projects and organizational 
tasks, and generally becoming a part of the SIPB community. 
Current keyholders can nominate members for keyholdership, usually after privately 
discussing that member's contributions to SIPB with other keyholders. 
After nomination, an election is held to determine whether the member 
will become a keyholder. If you're interested in becoming a keyholder, 
you should talk to the SIPB Chair! It's always okay to ask where you 
are on the path to keyholdership. 

For more information, read: /afs/sipb/admin/text/members/how-to-become-a-member.txt
(If you aren't familiar with afs yet, look at: https://sipb.mit.edu/doc/afs-and-you)

In general, /afs/sipb/admin/ has a lot of interesting material (meeting
minutes, policies, etc.) that are worth poking at next time you are 
putting off a problem set.

== Useful Websites ==

sipb.mit.edu - The SIPB website.
scripts.mit.edu - Scripts is a web-hosting service we run; use common web apps or write your own.
xvm.mit.edu - XVM is a virtual machine service, great for running your own server.
debathena.mit.edu - Download a version of Debathena suitable for your personal computer.
mirrors.mit.edu - offers on-campus mirrors for a number of Linux distros and other FOSS projects.


Congratulations on becoming a SIPB member! We hope to see you around!
"""}

class Error(Exception):
    pass

def run(*args):
    if OPTS.dryrun:
        print 'Would have run %s' % str(args)
    else:
        print 'Running:', args
        p = subprocess.Popen(args)
        p.communicate()
        if p.returncode:
            print 'Command returned %d' % p.returncode
            # raise Error()

def prompt(msg, default=True):
    if default:
        append = '[Yn]'
    else:
        append = '[yN]'
    input = raw_input('%s %s ' % (msg, append)).strip()
    if default:
        return not input.startswith('n')
    else:
        return input.startswith('y')

def normalize(relpath):
    return os.path.join(BASEDIR, relpath)

def add_to_list(list, username):
    if '@' in username:
        username = 'string:%s' % username
    print 'Adding %s to %s@ (%s)' % (username, list['name'], list['description'])
    run('blanche', '-a', username, list['name'])

def main():
    global OPTS

    parser = optparse.OptionParser(usage='usage: %prog [options] username')
    parser.add_option('-m', '--me', dest='me', help='Your username')
    parser.add_option('-n', '--dry-run', dest='dryrun',
                      action='store_true', default=False,
                      help='Just show what would happen')
    parser.add_option('-d', '--dont-email', dest='email', default=True,
                      action='store_false', help="Don't send a welcome email")
    parser.add_option('-l', '--dont-add-to-list', dest='list', default=True,
                      action='store_false',
                      help="Don't add to list of members")
    parser.add_option('-b', '--dont-blanche', dest='blanche', default=True,
                      action='store_false',
                      help="Don't blanche onto lists")
    (opts, args) = parser.parse_args()
    OPTS = opts

    if len(args) != 1:
        parser.print_help()
        return 1
    else:
        prospective = args[0]

    me = opts.me or os.getenv('ATHENA_USER') or pwd.getpwuid(os.getuid()).pw_name

    if opts.list:
        print 'Checking out the members_and_prospectives document'
        members_and_prospectives = normalize('members_and_prospectives')
        run('co', '-l', members_and_prospectives)

        with open(members_and_prospectives) as f:
            current_text = f.readlines()

        new_text = []
        for line in current_text:
            if line.startswith('####### Others'):
                date = datetime.datetime.now().strftime('%Y-%m-%d')
                newline = ('%-14s  prospective     %-22s  %s\n' %
                           (prospective, me, date))
                if opts.dryrun:
                    print 'Would have added line "%s"' % newline.strip()
                else:
                    print 'Adding line "%s"' % newline.strip()
                new_text.append(newline)
            new_text.append(line)

        if not opts.dryrun:
            with open(members_and_prospectives, 'w') as f:
                f.writelines(new_text)

        run('ci', '-u', '-mAdded %s to the list of members' % prospective, members_and_prospectives)

    if opts.blanche:
        for list in REQUIRED_LISTS:
            add_to_list(list, prospective)

        for list in OPTIONAL_LISTS:
            if not prompt('Should we add to %s@ (%s)' %
                          (list['name'], list['description'])):
                continue
            add_to_list(list, prospective)

    if opts.email:
        if '@' not in prospective:
            email = '%s@mit.edu' % prospective
        else:
            email = prospective
        username = email.split('@')[0]
        env = {'email' : email,
               'username' : username,
               'prospectivizer' : me}
        msg = MIMEText(WELCOME_EMAIL['__body__'] % env)
        msg.set_param('format', 'flowed')
        for k, v in WELCOME_EMAIL.iteritems():
            if k in ['__body__', 'Bcc']:
                continue
            msg[k] = v % env
        if opts.dryrun:
            print 'Would have sent welcome email to %s' % email
            print msg.as_string()
        else:
            print 'Sending welcome email to %s' % email
            p = subprocess.Popen(['/usr/lib/sendmail', email, WELCOME_EMAIL['Bcc']], stdin=subprocess.PIPE)
            p.communicate(input=msg.as_string())
            p.wait()
            if p.returncode:
                print 'Command returned %d' % p.returncode
    print 'All done!'

if __name__ == '__main__':
    sys.exit(main())
