import os
import subprocess
import glob

from sympy.utilities.misc import debug

here = os.path.dirname(__file__)
grammar_file = os.path.abspath(os.path.join(here, "LaTeX.g4"))
dir_latex_antlr = os.path.join(here, "_antlr")

header = '''
# encoding: utf-8

# *** GENERATED BY `setup.py antlr`, DO NOT EDIT BY HAND ***
#
# Generated from ../LaTeX.g4, derived from latex2sympy
#     latex2sympy is licensed under the MIT license
#     https://github.com/augustt198/latex2sympy/blob/master/LICENSE.txt
#
# Generated with antlr4
#    antlr4 is licensed under the BSD-3-Clause License
#    https://github.com/antlr/antlr4/blob/master/LICENSE.txt
'''


def check_antlr_version():
    debug("Checking antlr4 version...")

    try:
        debug(subprocess.check_output(["antlr4"])
              .decode('utf-8').split("\n")[0])
        return True
    except (subprocess.CalledProcessError, FileNotFoundError):
        debug("The antlr4 command line tool is not installed, "
              "or not on your PATH\n"
              "> Please install it via your preferred package manager")
        return False


def build_parser(output_dir=dir_latex_antlr):
    check_antlr_version()

    debug("Updating ANTLR-generated code in {}".format(output_dir))

    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    with open(os.path.join(output_dir, "__init__.py"), "w+") as fp:
        fp.write(header)

    args = [
        "antlr4",
        grammar_file,
        "-o", output_dir,
        # for now, not generating these as latex2sympy did not use them
        "-no-visitor",
        "-no-listener",
    ]

    debug("Running code generation...\n\t$ {}".format(" ".join(args)))
    subprocess.check_output(args, cwd=output_dir)

    debug("Applying headers and renaming...")
    # Handle case insensitive file systems. If the files are already
    # generated, they will be written to latex* but LaTeX*.* won't match them.
    for path in (glob.glob(os.path.join(output_dir, "LaTeX*.*")) +
        glob.glob(os.path.join(output_dir, "latex*.*"))):
        offset = 0
        new_path = os.path.join(output_dir,
                                os.path.basename(path).lower())
        with open(path, 'r') as f:
            lines = [line.rstrip() + '\n' for line in f.readlines()]

        os.unlink(path)

        with open(new_path, "w") as out_file:
            if path.endswith(".py"):
                offset = 2
                out_file.write(header)
            out_file.writelines(lines[offset:])

        debug("\t{}".format(new_path))

    return True


if __name__ == "__main__":
    build_parser()
