#!/usr/bin/env python
#
# @package      hubzero-cli
# @file         hzuseradd
# @author       David Benham <dbenham@purdue.edu>
# @copyright    Copyright (c) 2012 HUBzero Foundation, LLC.
# @license      http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
#
# Copyright (c) 2012 HUBzero Foundation, LLC.
#
# This file is part of: The HUBzero(R) Platform for Scientific Collaboration
#
# The HUBzero(R) Platform for Scientific Collaboration (HUBzero) is free
# software: you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# HUBzero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# HUBzero is a registered trademark of HUBzero Foundation, LLC.
#

import argparse
import grp
import hubzero.utilities.user
import hubzero.config.passwords
import hubzero.config.webconfig
import re
import traceback

# really, python has no int test without having to throw an exception?
def RepresentsInt(s):
	try: 
		int(s)
		return True
	except ValueError:
		return False



# ####################
# main

# parse the command line
parser = argparse.ArgumentParser()
parser.add_argument("username", help="username, alpha username")
parser.add_argument("--email", help="email address", default="")
parser.add_argument("--hubname", help="hubname, if not provided, will default to default hub", default="")
parser.add_argument("--joomlagid", help="Joomla specific GIDs, (18=Registered, 23=Manager, 24=Administrator, 25=Super Administrator)", default="18")
parser.add_argument("--gid", help="Linux GID, default is 100 (users)", default="100")
parser.add_argument("--home", help="set user home directory", default="")
parser.add_argument("--joomlauserid", help="specify pk id of user in jos_users table", default=-1)
parser.add_argument("--shell", help="specify pk id of user in jos_users table", default='/bin/bash')
parser.add_argument("--skipldap", help="skip adding user to ldap database", action="store_true", default=False)
parser.add_argument("--promptforpw", help="Prompt for password for user, otherwise generate random password", action="store_true", default=False)
parser.add_argument("--group", help="Create group for user", action="store_true", default=False)
parser.add_argument("--nocreatehome", help="skip creation of user home directory", action="store_true", default=False)
parser.add_argument("--disabled-password", dest="disabledpassword", help="disable user password", action="store_true", default=False)
parser.add_argument("--gecos", help="gecos field, see man page for /etc/passwd for more info", default="")

args = parser.parse_args()

# default email if it wasn't provided
if not args.email:
	defaultedEmail = True
	email = args.username + "@invalid"
else:
	defaultedEmail = False
	email = args.email

# default hubname if it wasn't provided
if not args.hubname:
	hubname = hubzero.config.webconfig.getDefaultSite()
	

# username tests
args.username = args.username.lower()
p = re.compile("[a-z][a-z0-9]*")
m = p.match(args.username)
if not m:
	print "username invalid - must be alphanumeric and must start with letter"
	exit(1)


# joomlagid tests
userTypeLookupDict = {18:"Registered", 23:"Manager", 24:"Administrator", 25:"Super Administrator"}

if RepresentsInt(args.joomlagid):
	if not args.joomlagid in ['18', '23', '24', '25']:
		print "invalid joomlagid (1) " + args.joomlagid
		exit(3)
	else:
		jgidNumber = args.joomlagid
		jgid = userTypeLookupDict[int(args.joomlagid)]

else:
	if not args.joomlagid in ["Registered", "Manager", "Administrator", "Super Administrator"]:
		print "invalid joomlagid (2) " + args.joomlagid
		exit(3)
	else:
		jgid = [key for key,val in userTypeLookupDict.items() if val==args.joomlagid ][0]
		jgidNumber = args.joomlagid

	
# gid tests
try:
	if not args.gid.isdigit():
		if not grp.getgrnam(args.gid):
			print "invalid gid"
			exit(3)
		else:
			gid = args.gid
			gidNumber = grp.getgrnam(args.gid)[2]
	else:
		if not grp.getgrgid(args.gid):
			print "invalid gid"
			exit(3)
		else:
			gid = grp.getgrgid(args.gid)[0]
			gidNumber = args.gid
except Exception as e:
	traceback.print_exc()
	print "Error: problem with provided gid"
	raise e
	

# email validity testing, if email was defaulted, don't check that.
if not defaultedEmail:
	p = re.compile("^[a-zA-Z0-9.]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$")
	m = p.match(email)
	if not m:
		print "invalid email"
		exit(4)

# prompt for a password, or create one from scratch
if not args.promptforpw:
	pw = hubzero.config.passwords.generateAlphaNumPassword(8)
else:
	
	# To make things easier, just alphanumberic, wierd characters are a pain
	validPW = False
	while not validPW:
		print "Enter user password and press return"
		pw = raw_input("Enter an password")

		p = re.compile("[a-zA-Z0-9]*")
		m = p.match(pw)

		if not m:
			print "Password invalid - must be alphanumeric"
		else:
			validPW = True

# parse gecos, it's a massive mess, but it's a comma delimited field used in the /etc/passwd file to store personal info
# it's comma delimited, and name is the first item in the list... right now we don't care about what else gets passed,
# but the first entry
gecos = args.gecos
gecosFields = gecos.split(",")
fullName = gecosFields[0].split(" ")

if len(fullName) == 3:
	firstname = fullName[0]
	middlename = fullName[1]
	lastname = fullName[2]
elif len(fullName) == 2:
	firstname = fullName[0]
	middlename = ""
	lastname = fullName[1]
else:
	firstname = fullName[0]
	middlename = ""
	lastname = ""
	
rc = hubzero.utilities.user.addhubuser(args.hubname,
                                  args.username, 
                                  firstname, 
                                  middlename,
                                  lastname, 
                                  email,
                                  pw,
                                  args.disabledpassword,
                                  jgid, 
                                  jgidNumber, 
                                  gid, 
                                  gidNumber, 
                                  args.joomlauserid,
                                  args.shell,
                                  args.nocreatehome,
                                  args.home,
                                  args.group,
                                  args.skipldap)

# only if we execute without errors
if not rc:
	# if user specified pw, no reason to tell them
	if not args.promptforpw:
		print "Autogenerated password for user is: " + pw


exit(0)