#! /bin/env python
# -*- coding: utf-8 -*-

#############################################################
#                                                           #
#   Author: Bertrand Neron               #
#   Organization:'Biological Software and Databases' Group, #
#                Institut Pasteur, Paris.                   #
#   Distributed under GPLv2 Licence. Please refer to the    #
#   COPYING.LIB document.                                   #
#                                                           #
#############################################################

import os , sys
MOBYLEHOME = None
if os.environ.has_key('MOBYLEHOME'):
    MOBYLEHOME = os.environ['MOBYLEHOME']
if not MOBYLEHOME:
    sys.exit( 'MOBYLEHOME must be defined in your environment' )
if ( os.path.join( MOBYLEHOME , 'Src' ) ) not in sys.path:
    sys.path.append( os.path.join( MOBYLEHOME , 'Src' ) )
      
      
from hashlib import md5
import os.path
      
from Mobyle.ConfigManager import Config  
from Mobyle.Transaction import Transaction
from Mobyle.Session import Session
from Mobyle.AuthenticatedSession import AuthenticatedSession
from Mobyle.Admin import Admin
from Mobyle.JobState import JobState , url2path


def get_session_key( email ):
    """
    """
    newMd5 = md5()
    newMd5.update( email )
    return newMd5.hexdigest()



if __name__ == '__main__':
    from optparse import OptionParser
    usage = """usage: %prog [options] old_email new_email
    
change authenticated session email and update jobs with the new session key
    """
    parser = OptionParser( usage= usage )
    parser.add_option( "-v" , "--verbose",
                      action= "count", 
                      dest = "verbosity", 
                      default = 0 ,
                      help = "increase the verbosity level of the output.") 
    options, args = parser.parse_args() 
    if len(args) != 2:
        parser.print_help( sys.stderr )
        sys.exit(1)
    import logging
    sh_formatter = logging.Formatter("%(levelname)-8s : L %(lineno)d : %(message)s")
    sh = logging.StreamHandler( sys.stderr ) 
    sh.setFormatter(sh_formatter)
    logger = logging.getLogger('mobemail')  
    logger.addHandler( sh )
    
    if options.verbosity == 0:
        logger.setLevel( logging.ERROR )
    elif options.verbosity == 1:
        logger.setLevel( logging.WARNING )
    elif options.verbosity == 2:
        logger.setLevel( logging.INFO )
    elif options.verbosity == 3:
        logger.setLevel( logging.DEBUG )
    
    old_email = args[0]
    new_email = args[1]
    
    config = Config()
    old_session_key = get_session_key( old_email )
    new_session_key = get_session_key( new_email )
    old_session_dir = os.path.normpath( os.path.join( config.user_sessions_path() , AuthenticatedSession.DIRNAME , old_session_key ))
    new_session_dir = os.path.normpath( os.path.join( config.user_sessions_path() , AuthenticatedSession.DIRNAME , new_session_key ))   
    if not os.path.exists( old_session_dir ): 
        msg = "The session corresponding to %s does not exists" % old_email
        logger.critical(msg)
        sys.exit(2)
    if os.path.exists( new_session_dir):
        msg = "The session corresponding to %s already exists" % new_email
        logger.critical(msg)
        sys.exit(3)
    transaction =  Transaction( os.path.normpath( os.path.join( old_session_dir , Session.FILENAME)), Transaction.WRITE )
    tr_email =  transaction.getEmail()
    if old_email != tr_email:
        if new_email == tr_email:
            logger.warning( "the email of session is already set to new email: continue")
        else:
            msg = "The email %s in the session %s does not match the provided email %s"%(old_email, old_session_dir , tr_email)
            logger.critical(msg)
            sys.exit(3)
    logger.debug("set session email to %s" % new_email)        
    transaction.setEmail( new_email )
    transaction.setID( new_session_key )
    transaction.commit()
    transaction =  Transaction( os.path.normpath( os.path.join( old_session_dir , Session.FILENAME)), Transaction.READ )
    all_jobs = transaction.getAllJobs()
    logger.debug("get session jobs")  
    transaction.commit()
    for j in all_jobs:
        job_path = url2path( j['jobID'] )
        if not os.path.exists(job_path):
            logger.debug("The job %s does not exists : continue" % job_path)
            continue
        index_path = os.path.join( job_path , 'index.xml')
        job_dir_mtime = os.path.getmtime( job_path )
        job_dir_atime = os.path.getatime( job_path )
        index_mtime = os.path.getmtime( os.path.join( job_path , 'index.xml') )
        index_atime = os.path.getatime( os.path.join( job_path , 'index.xml') )
        job =  JobState( job_path )
        job_email = job.getEmail()
        if old_email != job_email:
            if new_email == job_email:
                logger.warning( "the email of job %s is already set to new email: continue" % job_path)
                continue
            msg = "The email in the job %s does not match the provided email %s"%(job_path , job_email)
            logger.error(msg)
            sys.exit(3)
        logger.debug("job %s set email %s -> %s"% (job.getDir() , old_email, new_email )) 
        job.setEmail( new_email )
        logger.debug("job %s set session to %s"% (job.getDir(),new_session_key))
        job.setSessionKey( new_session_key )
        job.commit()
        logger.debug("job admin %s set email %s -> %s"%(job.getDir() , old_email, new_email))
        adm = Admin(job_path )
        logger.debug("job admin %s set session to %s" % (job.getDir(), new_session_key))
        adm.setEmail( new_email )
        adm.setSession( new_session_key )
        adm.commit()
        os.utime( index_path , ( index_atime , index_mtime ) )
        os.utime( job_path , ( job_dir_atime , job_dir_mtime ) )
    logger.debug("rename session  %s -> %s"% (old_session_dir , new_session_dir)) 
    os.rename(old_session_dir, new_session_dir)     
                                                                    