"""
open/DurusWorks/qpy/compile.py

"""
from os import stat, listdir
from os.path import join
import py_compile
import re
import symbol
import sys
import token


if sys.version < "3":
    import __builtin__ as builtins
else:
    import builtins

if sys.platform.startswith('java'):
    from qpy.compile_jython import PYC, compile, get_code, get_parse_tree
else:
    from qpy.compile_cpython import PYC, compile, get_code, get_parse_tree

get_parse_tree # for checker
get_code

_annotation_re = re.compile(
    r"^(?P<indent>[ \t]*)def(?:[ \t]+)"
    r"(?P<name>[a-zA-Z_][a-zA-Z_0-9]*)"
    r"(?:[ \t]*:[ \t]*)(?P<type>xml|str)(?:[ \t]*)"
    r"(?:[ \t]*[\(\\])",
    re.MULTILINE|re.VERBOSE)

_template_re = re.compile(
    r"^(?P<indent>[ \t]*) def (?:[ \t]+)"
    r" (?P<name>[a-zA-Z_][a-zA-Z_0-9]*)"
    r" (?:[ \t]*) \[(?P<type>plain|html)\] (?:[ \t]*)"
    r" (?:[ \t]*[\(\\])",
    re.MULTILINE|re.VERBOSE)

def translate_tokens(buf):
    """
    def f:xml( ... )  -> def f__xml_template__(...):
    def f:str( ... )  -> def f__str_template__(...):

    and, for backward compatibility,

    def foo [html] (...): -> def foo__xml_template__(...):
    def foo [plain] (...): -> def foo__str_template__(...):
    """
    def replacement(match):
        if match.group('type') in ('xml', 'html'):
            template_type = 'xml'
        elif match.group('type') in ('str', 'plain'):
            template_type = 'str'
        return '%sdef %s__%s_template__(' % (match.group('indent'),
                                 match.group('name'),
                                 template_type)
    translated = _annotation_re.sub(replacement, buf)
    translated = _template_re.sub(replacement, translated)
    return translated

def timestamp(filename):
    try:
        s = stat(filename)
    except OSError:
        return None
    return s.st_mtime

def compile_qpy_file(source_name):
    """(source_name:str)
    Compile the given filename if it is a .qpy file and if it does not already
    have an up-to-date .pyc file.
    """
    if source_name[-4:] == '.qpy':
        compile_time = timestamp(source_name[:-4] + PYC)
        if compile_time is not None:
            source_time = timestamp(source_name)
            if compile_time >= source_time:
                return # already up-to-date
        try:
            compile(source_name)
        except py_compile.PyCompileError:
            exception = sys.exc_info()[1]
            exception_msg = getattr(exception, 'msg') or ''
            exception_file = getattr(exception, 'file') or ''
            if exception_msg and exception_file:
                exception.msg = ("\n\nCan't compile %s:\n" % exception_file) + exception_msg
            raise

def compile_qpy_files(path):
    """(path:str)
    Compile the .qpy files in the given directory.
    """
    for name in listdir(path):
        if name[-4:] == '.qpy':
            compile_qpy_file(join(path, name))


if __name__ == '__main__':
    import qpy.__main__
