#! /usr/bin/env python3

################################################################################
#
# Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors
#
# This file is a part of the MadGraph5_aMC@NLO project, an application which 
# automatically generates Feynman diagrams and matrix elements for arbitrary
# high-energy processes in the Standard Model and beyond.
#
# It is subject to the MadGraph5_aMC@NLO license which should accompany this 
# distribution.
#
# For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch
#
################################################################################

"""This is the main executable, a simple frontend to set up the PYTHONPATH
and call immediately the command line interface scripts"""

import sys
if   sys.version_info < (3, 7):
    sys.exit('MadGraph/aMCatNLO 5 works only with python 3.7 or later .\n\
               Please upgrate your version of python.')

try:
    import six
except ImportError:
    message = 'madgraph requires the six module. The easiest way to install it is to run "pip install six --user"\n'
    message += 'in case of problem with pip, you can download the file at https://pypi.org/project/six/ . It has a single python file that you just need to put inside a directory of your $PYTHONPATH environment variable.'
    sys.exit(message)
    
import os
import optparse

# Get the directory of the script real path (bin)
# and add it to the current PYTHONPATH

root_path = os.path.dirname(os.path.realpath( __file__ ))
sys.path.insert(0, root_path)



class MyOptParser(optparse.OptionParser):
    
    class InvalidOption(Exception): pass

    def error(self, msg=''):
        raise MyOptParser.InvalidOption(msg)




# Write out nice usage message if called with -h or --help
usage = "usage: %prog [options] [FILE] "
parser = MyOptParser(usage=usage)
parser.add_option("-l", "--logging", default='INFO',
                  help="logging level (DEBUG|INFO|WARNING|ERROR|CRITICAL) [%default]")
parser.add_option("","--web", action="store_true", default=False, dest='web', \
                 help='force to be in secure mode')
parser.add_option("","--debug", action="store_true", default=False, dest='debug', \
                 help='force to launch debug mode')
parser_error = ''
done = False
for i in range(len(sys.argv)-1):
    try:
        (options, args) = parser.parse_args(sys.argv[1:len(sys.argv)-i])
        done = True
    except MyOptParser.InvalidOption as error:
        pass 
    else:
        args += sys.argv[len(sys.argv)-i:]
if not done:
    # raise correct error:
    try:
        (options, args) = parser.parse_args()
    except MyOptParser.InvalidOption as error:
        print(error)
        sys.exit(2)  

if len(args) == 0:
    args = ''

import subprocess

# Check if optimize mode is (and should be) activated
if __debug__ and not options.debug and \
    (not os.path.exists(os.path.join(root_path,'../..', 'bin','create_release.py')) or options.web):
        print( 'launch in debug mode')
        subprocess.call([sys.executable] + ['-O'] + sys.argv)
        sys.exit()

import logging
import logging.config

try: 
    import readline
except ImportError:
    try:
        import pyreadline as readline
    except:
        print( "For tab completion and history, install module readline.")
else:
    import rlcompleter

    if 'r261:67515' in sys.version and  'GCC 4.2.1 (Apple Inc. build 5646)' in sys.version:
        readline.parse_and_bind("bind ^I rl_complete")
        readline.__doc__ = 'libedit'  
    
    elif hasattr(readline, '__doc__'):
        if 'libedit' not in readline.__doc__:
            readline.parse_and_bind("tab: complete")
        else:
            readline.parse_and_bind("bind ^I rl_complete")
    else:
        readline.__doc__ = 'GNU'
        readline.parse_and_bind("tab: complete")

    # charge history file
    try:
        legacy_state_dir = os.path.join(os.environ['HOME'], '.mg5')

        if os.path.exists(legacy_state_dir):
            state_dir = legacy_state_dir
        else:
            state_dir = os.getenv('XDG_STATE_HOME', os.path.join(os.environ['HOME'], '.local', 'state'))

        history_file = os.path.join(state_dir, "me5history")
        readline.read_history_file(history_file)

    except:
        pass

try:
   import psyco
   psyco.full()
except:
   pass

if __debug__:
        print( 'Running MG5 in debug mode')


# Set logging level according to the logging level given by options
#logging.basicConfig(level=vars(logging)[options.logging])
import internal.coloring_logging
try:
    if __debug__ and options.logging == 'INFO':
        options.logging = 'DEBUG'    
    if options.logging.isdigit():
        level = int(options.logging)
    else:
        level = eval('logging.' + options.logging)

    logging.config.fileConfig(os.path.join(root_path, 'internal', 'me5_logging.conf'))
    logging.root.setLevel(level)
    logging.getLogger('madgraph').setLevel(level)
except:
    pass
import internal.amcatnlo_run_interface as cmd_interface

#Source use this executable for compilation always allow it
force_run = False
if (args and args[0] == 'treatcards'):
    force_run=True
    
# check that madgraph is not in PYTHONPATH which can be problematic
try:
    import madgraph
except ImportError:
    pass
else:
    logger.getLogger('madgraph').error('Looks like you do have madgraph in your PYTHONPATH (or you run this executable    from the main MG5aMC directory). This executable will likely not work in such case.')


# Call the cmd interface main loop
try:
    if (args and os.path.isfile(args[0])):
        # They are an input file 
        input_file = args[0]
        if options.web:
            cmd_line = cmd_interface.aMCatNLOCmd()
            cmd_line.debug_output = os.path.join(os.path.dirname(input_file),'generation.log')
            cmd_line.use_rawinput = False
            cmd_line.haspiping = False
            cmd_line.run_cmd('import command ' + input_file)
            cmd_line.run_cmd('quit')      
        else:
            cmd_line = cmd_interface.aMCatNLOCmdShell()
            cmd_line.use_rawinput = False
            cmd_line.haspiping = False
            cmd_line.run_cmd('import command ' + input_file)
            cmd_line.run_cmd('quit')
    elif args:
        # a single command is provided
        if options.web:
            cmd_line = cmd_interface.aMCatNLOCmd(force_run=force_run)
        else:
            cmd_line = cmd_interface.aMCatNLOCmdShell(force_run=force_run)
        if not hasattr(cmd_line, 'do_%s' % args[0]):
            if parser_error:
                print( parser_error)
                print( 'and %s  can not be interpreted as a valid command.' % args[0])
            else:
                print( 'ERROR: %s  not a valid command. Please retry' % args[0])
        else:
            cmd_line.use_rawinput = False    
            cmd_line.run_cmd(' '.join(args))
            cmd_line.run_cmd('quit')
    else:
        # Interactive mode
        if options.web:
            cmd_line = cmd_interface.aMCatNLOCmd()
            cmd_line.cmdloop()
        else:
            cmd_line = cmd_interface.aMCatNLOCmdShell()
            cmd_line.cmdloop()

except KeyboardInterrupt:
    print( 'writting history and directory and quit on KeyboardInterrupt')
    pass
except cmd_interface.aMCatNLOAlreadyRunning as error:
    logging.error(str(error))
    sys.exit()
try:
    readline.set_history_length(100)
    if not os.path.exists(state_dir):
        os.mkdir(state_dir)
    readline.write_history_file(history_file)
except:
    pass

try:
    if cmd_line.history[-1] not in ['EOF','quit','exit']:
        cmd_line.results.store_result()
except:
    print( error)
    pass


try:
    # Remove lock file
    os.remove(os.path.join(root_path,os.pardir, 'RunWeb'))
except:
    pass
