import sys
import os
sys.path.insert(0, os.environ["QUEX_PATH"])

from   quex.blackboard                    import setup, \
                                                 E_Compression
import quex.blackboard                    as     blackboard
from   quex.input.command_line.GetPot     import GetPot
import quex.input.command_line.validation as     validation
from   quex.input.setup                   import SETUP_INFO,               \
                                                 SetupParTypes,            \
                                                 global_extension_db,      \
                                                 global_character_type_db, \
                                                 command_line_args_defined, \
                                                 command_line_arg_position, \
                                                 E_Files

from   quex.output.cpp.token_id_maker     import parse_token_id_file

from   quex.engine.misc.file_in           import error_msg,                \
                                                 verify_word_in_list,      \
                                                 read_namespaced_name,     \
                                                 read_integer,             \
                                                 open_file_or_die
import quex.engine.codec_db.core            as codec_db
from   quex.engine.generator.languages.core import db as quex_core_engine_generator_languages_db
from   quex.engine.generator.action_info    import CodeFragment

from   quex.DEFINITIONS import QUEX_VERSION

from   StringIO import StringIO
from   operator import itemgetter

class ManualTokenClassSetup:
    """Class to mimik as 'real' TokenTypeDescriptor as defined in 
       quex.input.files.token_type.py. Names and functions must remain
       as they are for compatibility.
    """
    def __init__(self, FileName, ClassName, NameSpace, ClassNameSafe, TokenIDType):
        
        self.__file_name       = FileName
        self.class_name        = ClassName
        self.name_space        = NameSpace
        self.class_name_safe   = ClassNameSafe

        self.column_number_type = CodeFragment("size_t")
        self.line_number_type   = CodeFragment("size_t")
        self.token_id_type      = CodeFragment(TokenIDType)

    def get_file_name(self):
        return self.__file_name

    def manually_written(self):
        return True

def do(argv):
    global setup

    try:    
        idx = argv.index("--token-class-file")
        if idx + 1 < len(argv): idx += 1
        else:                   idx  = None
    except: 
        idx = None 

    if idx is not None:
        extra_argv = __extract_extra_options_from_file(argv[idx])
        if extra_argv is not None: argv.extend(extra_argv)

    command_line = __interpret_command_line(argv)
    if command_line is None:
        return False

    return __perform_setup(command_line, argv)

def __perform_setup(command_line, argv):
    """RETURN:  True, if process needs to be started.
                False, if job is done.
    """
    global setup

    # (*) Classes and their namespace
    __setup_analyzer_class(setup)
    __setup_token_class(setup)
    __setup_token_id_prefix(setup)
    __setup_lexeme_null(setup)       # Requires 'token_class_name_space'

    # (*) Output programming language        
    setup.language = setup.language.upper()
    verify_word_in_list(setup.language,
                        quex_core_engine_generator_languages_db.keys(),
                        "Programming language '%s' is not supported." % setup.language)
    setup.language_db  = quex_core_engine_generator_languages_db[setup.language]
    setup.extension_db = global_extension_db[setup.language]

    # Is the output file naming scheme provided by the extension database
    # (Validation must happen immediately)
    if setup.extension_db.has_key(setup.output_file_naming_scheme) == False:
        error_msg("File extension scheme '%s' is not provided for language '%s'.\n" \
                  % (setup.output_file_naming_scheme, setup.language) + \
                  "Available schemes are: %s." % repr(setup.extension_db.keys())[1:-1])

    # Before file names can be prepared, determine the output directory
    # If 'source packaging' is enabled and no output directory is specified
    # then take the directory of the source packaging.
    if setup.source_package_directory != "" and setup.output_directory == "":
        setup.output_directory = setup.source_package_directory

    if setup.buffer_codec in ["utf8", "utf16"]:
        setup.buffer_codec_transformation_info = setup.buffer_codec + "-state-split"

    elif setup.buffer_codec_file != "":
        try: 
            setup.buffer_codec = os.path.splitext(os.path.basename(setup.buffer_codec_file))[0]
        except:
            error_msg("cannot interpret string following '--codec-file'")

        setup.buffer_codec_transformation_info = codec_db.get_codec_transformation_info(FileName=setup.buffer_codec_file)