#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import grp, pwd
from argparse import ArgumentParser
from optparse import OptionParser
#from scribe.ldapconf import USERS_DN, SMB_SERVEUR
from samba.samdb import SamDB
from samba.auth import system_session
from samba import getopt, generate_random_password
import ldb
from configobj import ConfigObj

conffile = "/etc/eole/ldapconf.conf"
dico = ConfigObj(conffile)

class EtabStr(str):
    def __mod__(self, dico):
        dico.setdefault('etab', num_etab)
        if dico['etab'] is None:
            dico['etab'] = num_etab
        return str.__mod__(self, dico)


num_etab = str(dico['numero_etab'])
acad = str(dico['nom_academie'])
SUFFIX = dico.get('suffix', 'o=gouv,c=fr')
RACINE = "ou=%s,ou=education,%s" % (acad, SUFFIX)
BRANCHE_ETAB = "ou=%%(etab)s,%s" % (RACINE)
USERS_DN = EtabStr("ou=utilisateurs,%s" % BRANCHE_ETAB)
SMB_SERVEUR = str(dico["smb_netbios_name"])

class OwnSamDB(SamDB):
    def add(self,
            ldif,
            ):
        ldif['objectClass'] = ['user', 'posixAccount', 'shadowAccount', 'inetOrgPerson', 'sambaSamAccount']
        super().add(ldif)


def new_user(args):
    parse = OptionParser()
    lp = getopt.SambaOptions(parse).get_loadparm()
    creds = getopt.CredentialsOptions(parse).get_credentials(lp)
    samdb = OwnSamDB(session_info=system_session(), credentials=creds, lp=lp)
    user_dn = args.o + ',' + USERS_DN % {}
    gid = grp.getgrnam(args.g).gr_gid
    if args.F:
        profilepath = args.F
    else:
        profilepath = None
    samdb.newuser(username=args.name, password=generate_random_password(128, 128), userou=user_dn[:- (len(samdb.domain_dn()) + 1)], force_password_change_at_next_login_req=args.A == 1, useusernameascn=True, surname=args.name, givenname=args.name, homedrive=args.D, homedirectory=args.C, loginshell=args.s, profilepath=profilepath, gidnumber=gid)
    # add user in group
    samdb.add_remove_group_members(args.g, [args.name], add_members_operation=True)
    for groupname in args.G.split(','):
        if groupname.lower() == 'domainusers':
            groupname = 'domain users'
            continue
        elif groupname.lower() == 'domainadmins':
            groupname = 'domain admins'
        elif groupname.lower() == 'printoperators':
            groupname = 'print operators'
        samdb.add_remove_group_members(groupname, [args.name], add_members_operation=True)
    uid = pwd.getpwnam(args.name).pw_uid
    ldif = """
dn: {user_dn}
changeType: modify
add: uidNumber
uidNumber: {uid}
add: uid
uid: {name}
replace: userAccountControl
userAccountControl: 544
replace: accountExpires
accountExpires: 0
""".format(user_dn='cn=' + args.name + ',' + user_dn, uid=uid, name=args.name)
    samdb.modify_ldif(ldif)
#    samdb.setexpiry("(&(objectClass=user)(sAMAccountName={}))".format(args.name), 2678400000, no_expiry_req=None)


if __name__ == '__main__':
    parser = ArgumentParser()
    parser.add_argument('-a', help='is a Windows User (otherwise, Posix stuff only)', action='store_true')
    parser.add_argument('-A', help='can change password ? 0 if no, 1 if yes')
    parser.add_argument('-D', help='sambaHomeDrive (letter associated with home share, like \'H:\')')
    parser.add_argument('-H', help='sambaAcctFlags (samba account control bits like \'[NDHTUMWSLKI]\')')
    parser.add_argument('-o', help='add the user in the organizational unit (relative to the user suffix. Ex: \'ou=admin,ou=all\')')
    parser.add_argument('-s', help="shell")
    parser.add_argument('-d', help="home")
    parser.add_argument('-C', help="sambaHomePath (SMB home share, like '\\PDC-SRV\homes')")
    parser.add_argument('-F', help="sambaProfilePath (profile directory, like '\\PDC-SRV\profiles\foo')")
    parser.add_argument('-g', help="gid")
    parser.add_argument('-G', help="supplementary comma-separated groups")
    parser.add_argument('name')

    args = parser.parse_args()
    if not args.a:
      raise Exception('-a mandatory')
    new_user(args)
