#!/usr/local/bin/python3.11
import os, sys, argparse, shlex
from cpp2py.cpp2desc import Cpp2Desc
import cpp2py.libclang_config as config

#
print("Welcome to C++2py")

# --- Parsing the arguments of the script and options

parser = argparse.ArgumentParser(description="""
Generate the C++/Python wrapper desc file from C++ header code
""")

parser.add_argument('filename', help = "Name of the file to parse")

parser.add_argument('--regenerate', '-r',  action='store_true', help="Rebuild the desc file with the shell command written at its head (ignores all other options")

parser.add_argument('--converter', '-C',   action='append',  help='Path to the converter DIRS')

parser.add_argument('--namespace', '-N', action='append',  help="Specify the namespace to explore for classes and function to wrap", default= [])
parser.add_argument('--only', default = '',  help="Specify functions or class to be wrapped")
parser.add_argument('--outputname', '-o',  help="Name of the xxx_desc.py file [default is same as the filename]", default = '')
parser.add_argument('--modulename', '-m',  help="Name of the Python module [default ='', it will be modulename", default = '')
parser.add_argument('--appname', '-a',  help="Name of the Python module [default ='', it will take the name of file", default = '')
parser.add_argument('--moduledoc',  help="Documentation of the module", default = '')
parser.add_argument('--properties', '-p',  action='store_true',
        help="""Transforms i) every method with no arguments into read-only property
                ii) every method get_X into read-only property
                iii) every couple of methods get_X, set_X into rw property
              """)
parser.add_argument('--members_read_only',  action='store_true', help="""Makes members read only [default = True]""")
parser.add_argument('--parse-all-comments',  action='store_true', help="Grab all comments, including non doxygen like [default = True]")

parser.add_argument('--libclang_location', help='Location of the libclang', default = config.LIBCLANG_LOCATION)
parser.add_argument('--includes', '-I', action='append',  help='Includes to pass to clang')
parser.add_argument('--system_includes', '-isystem', action='append',  help='System includes to pass to clang')
parser.add_argument('--cxxflags', default = '', help='Options to pass to clang')
parser.add_argument('--target_file_only', action='store_true', help='Disable recursion into included header files')

args = parser.parse_args()

if args.regenerate : 
    assert not (args.cxxflags or args.includes or args.system_includes or args.converter or args.namespace or args.only or args.properties), "-r option must be alone"
    f= open(args.filename)
    f.readline()
    shell_command = f.readline()[2:].strip()
    args = parser.parse_args(args = shlex.split(shell_command)[1:]) # reparse now that the arguments are changed.
else:
    # the instruction that created this file
    f = lambda x : x if not (x.startswith('--cxxflags') or x.startswith('--only') or x.startswith('--moduledoc'))  else '%s="%s"'%tuple(x.split('=', 1)) 
    shell_command = 'c++2py ' + ' '.join(f(x) for x in sys.argv[1:]) 

# A few variables    
args.includes = (args.includes or [])
args.system_includes = (args.system_includes or [])
filename_1 = os.path.split(args.filename)[1].split('.',1)[0]

# Add the environment variables
cxx_env = os.getenv('CXXFLAGS').split() if os.getenv('CXXFLAGS') else []

# ---------------------------------------------------------
# Create the worker. It parses the file       
W= Cpp2Desc(filename = args.filename, 
            converters = args.converter or (),  
            namespaces= args.namespace, 
            classes= args.only.split(), 
            use_properties = args.properties,
            modulename = args.modulename or filename_1,
            appname = args.appname or args.modulename or filename_1,
            moduledoc = args.moduledoc,
            members_read_only = args.members_read_only,
            includes = args.includes or (), 
            system_includes = args.system_includes or (),
            compiler_options = args.cxxflags.split(' ') + cxx_env,
            libclang_location = args.libclang_location,
            shell_command = shell_command,
            parse_all_comments = args.parse_all_comments,
            namespace_to_factor= (), # unused now
            target_file_only = args.target_file_only
            )

# Make the desc file
W.generate_desc_file(output_filename = (args.outputname or filename_1) + "_desc.py")

