import sys, os, re, textwrap, pprint

basedir = f'{os.environ["KLAMMERTEXT_HOME"]}/sks'
sys.path = [f"{basedir}/kutil"] + sys.path
sys.path = [f"{basedir}/target"] + sys.path

import kutil
import html_util

def tex_to_pdf(text):
    print("in tex_to_pdf")
    


def expand_whitespace_markers(text, K=None):
    def count(count_match):
        count = int(count_match) if count_match else 1
        return count
    def replace_spaces(match):
        return " " * count(match.group(1))
    def replace_newlines(match):
        return "\n" * count(match.group(1))

    result = text

    # result = re.sub(r"\s*#-\s*", "", result)

    # space_pat = re.compile(r" *#\+(\d*) *", re.S)
    # print("hits:", space_pat.findall(text))

    # for p in space_pat.findall(text):
    #     print("FOUND:", p)


    #
    #result = re.sub(" ", "SPACE", result)
    #result = re.sub("#/", "\n", result)
    #result = re.sub("X", " ", result)
    
    result = re.compile(r" *#- *", re.S).sub("", result)
    result = re.compile(r" *#\+(\d*) *", re.S).sub(replace_spaces, result)
    result = re.compile(r"\s*\#\/(\d*)\s*", re.S).sub(replace_newlines, result)

    #print(result)
    #sys.exit(0)
    #print("expand_whitespace_markers", text, result)
    return result


def handle_dashes(html_text, K=None):
    def replace(match):
        tag_start, text, tag_end = match.groups()
        text = re.sub("__MDASH__", "---", text)
        text = re.sub("__NDASH__", "--", text)
        result = f"{tag_start}{text}{tag_end}"
        return result
    result = html_text
    result = re.compile('(<span class="monospace">)(.*?)(</span>)', re.S).sub(replace, result)
    result = re.sub("__MDASH__", "&#x2014;", result);
    result = re.sub("__NDASH__", "&#x2013;", result);
    return result

def add_tex_caption_numbers(tex_text, K=None):
    chapter_pat = re.compile(r"\\section\\{")
    index = {}
    result = ""
    chapter_number = 1
    for line in tex_text.split("\n"):
        if chapter_pat.search(line):
            chapter_number += 1
            reset_indices(index)
        if kutil.caption_delimiter() in line:
            before, caption_type, caption, after = line.split(kutil.caption_delimiter())
            if index.get(caption_type) is None:
                index[caption_type] = 1
            n = index[caption_type]
            number = f"{chapter_number}.{n}" if chapter_number != 0 else n
            line = f"{before}{caption_type} {number} {caption}{after}"
            index[caption_type] += 1
        result += line + "\n"
    return result


def remove_redundant_vspace(tex_text, K=None):
    #print("remove_redundant_vspace")
    rgx = re.compile(r"(\\vspace\*\{-[^}]+\})\s*\\vspace\*\{-[^}]+\}", re.S)
    return rgx.sub(r"\1", tex_text)

def restore_backslash(tex_text, K=None):
    #print("restore backslash")
    #return re.compile(r"\^/").sub(r"\\", tex_text)
    return re.sub("\6", "", tex_text)

#--------------------------------------------------------------------------------

def levels_to_section(levels):
    result = ".".join([str(e) for e in levels])
    result = re.sub(r"\.0", "", result)
    return result

def chapter_title_span():
    return '<span class="chapter_title">'

def add_html_section_numbers(html_text, K=None, start=0):
    depth = 6
    levels = [start-1] + ([0] * (depth-1))
    section_pat = re.compile(r"(.*?)<h(\d)(.*?)>(.*?)</h\2>")
    id_pat = re.compile(r'.*?id="([-\w]+)".*', re.S)
    result = ""
    id_number = 1
    id_map = []
    for line in html_text.split('\n'):
        match = section_pat.match(line)
        if match:
            pre, level, attr, text = match.groups()
            id_match = id_pat.fullmatch(attr)
            if id_match:
                id = id_match.group(1)
            else:
                id = f"id{id_number}"
                attr = " " + f'id="{id}" {attr}'.strip()
                id_number += 1
            level = int(level)
            levels[level-1] = levels[level-1] + 1
            for i in range(level, depth):
                levels[i] = 0
            section = levels_to_section(levels)
            line = f'{pre}<h{level}{attr}>{chapter_title_span()}{section}&#160;&#160;</span>{text}</h{level}>'
            id_map.append([level, section, id, text])
        result += line + "\n"
    [print(e) for e in id_map]
    return result, id_map

def make_html_table_of_contents(titles):
    result = '<div id="_toc" class="toc-title">Table of contents</div>\n'
    for level, section, id, text in titles:
        result += f'<div class="level{level}"><a href="#{id}" class="level">{section} {text}</a></div>\n'
    return result

def process_html_sections(html_text, K=None, start=1):
    html, id_map = add_html_section_numbers(html_text)
    toc = make_html_table_of_contents(id_map)
    result = re.sub(r'(<div id="middle">)', rf"\1\n{toc}", html)
    return result


def reset_indices(indices):
    for key in indices.keys():
        indices[key] = 1

def add_html_caption_numbers(html_text, K=None):
    chapter_pat = re.compile(rf"{chapter_title_span()}(\d+)</span>")
    index = {}
    result = ""
    chapter_number = ""
    for line in html_text.split("\n"):
        if '<span' in line:
            match = chapter_pat.search(line)
            print(match.groups())
            if match and match.group(1) != "0":
                chapter_number = f"{match.group(1)}."
                reset_indices(index)
        if kutil.caption_delimiter() in line:
            before, caption_type, caption, after = line.split(kutil.caption_delimiter())
            if index.get(caption_type) is None:
                index[caption_type] = 1
            n = index[caption_type]
            line = f"{before}{caption_type} {chapter_number}{n} {caption}{after}"
            index[caption_type] += 1
        result += line + "\n"
    return result



def escape_pre_angle_brackets(code, K=None):
    def replace(match):
        code = re.sub(r"<", "&#x003C;", match.group(1))
        return f"<pre>{code}</pre>"
    pat = re.compile("<pre>(.*?)</pre>", re.S)
    return pat.sub(replace, code)

def block_elements():
    return """
address article aside blockquote details dialog dd div dl dt fieldset
figcaption figure footer form h0 h1 h2 h3 h4 h5 h6 header hgroup hr li
main nav ol p section table ul td tr pre
""".strip().split()
    

def not_a_block(par):
    if par.strip()[0] != "<":
        return True
    pat = re.compile(r'^</?([^\s>]+).*?>', re.S|re.M)
    match = pat.match(par.strip())
    return match.group(1) not in block_elements()

def make_paragraphs(html_text, K):
    def replace(match):
        before, content, after = match.groups()
        result = ""
        for par in [e.strip() for e in
                    re.compile(r"\n *(\n *)+", re.S).split(content)]:
            if par.strip() and not_a_block(par):
                #jpar = "\n".join(textwrap.wrap(par, width=80))
                #result += f"\n<p>\n{jpar}\n</p>\n"
                jpar = "\n".join(textwrap.wrap(f"<p>{par}</p>", width=80))
                result += f"\n{jpar}\n"
            else:
                result += f"\n{par}\n"
        result = re.compile(r"\s*</(\w+)>\n<\1>").sub(r"\n</\1>\n\n<\1>", result)
        return f"{before}{result}{after}"
    pat = re.compile(r'(.*?<div id="middle">)(.*?)(</div>\s*<div id="bottom">.*)', re.S)
    match = pat.match(html_text)
    result = pat.sub(replace, html_text)
    result = re.compile(r"</td>\s+<td>", re.S).sub("</td>\n<td>", result)
    result = re.compile(r"\n *(\n *)+", re.S).sub("\n\n", result)
    return result


def indent_html(filename, K):
    #print('indent_html')
    html_util.html_indent(filename)

def copy_html_resources(filename, K):
    output_dir = os.path.dirname(K._output_filename) or "."
    css_dir = f"{output_dir}/{html_util.css_reldir()}"
    kutil.make_dir_if_necessary(css_dir, delete_contents=True)
    for basename, source in kutil.sks_files_of_type("css"):
        command = f"cp {source} {css_dir}/{basename}.css"
        os.system(command)


# def latex_escapes(latex_text):
#     return latex_text
#     result = latex_text
#     result = re.sub('#', '\\#', result)
#     result = re.sub('\^', '\\^', result)
#     result += "LATEX"
#     return result

# def restore_backslash(latex_text, K): # ?
#     return latex_text
#     print(latex_text)
#     print("restore_backslash")
#     result = latex_text
#     result = re.sub('\b', r'\\b', result)
#     result = re.sub(r'\\t', r'\\b', result)
#     return result


def make_pdf_from_tex(filename, K, twice=True):
    #debug_mode = int(K.K_verbose_level) > 1
    verbose_level = int(K.K_verbose_level)
    pathname = os.path.abspath(filename)
    dirname, filename = os.path.split(pathname)
    basename, ext = os.path.splitext(filename)
    command = f"mv {pathname} {dirname}/{basename}.tex"
    log_file = f"{dirname}/{basename}.log"
    pdf_file = f"{dirname}/{basename}.pdf"
    result = os.system(command)
    #debug_mode = True
    if verbose_level == 3:
        remove_log = ''
    else:
        dbg_log = "/dev/null"
        remove_log = ' >{} 2>&1'.format(dbg_log)

    env_var = "KLAMMERTEXT_TEXLIVE_BIN"
    texbin = os.environ.get(env_var)
    if texbin is None:
        msg = f"The directory of TeX Live commands must be defined by ${env_var}"
        raise Exception(msg)

    latex_command = f"{texbin}/xelatex"
    #latex_command = f"{texbin}/pdflatex"

    if not os.path.exists(latex_command):
        raise Exception(f"LaTeX command not found: {latex_command}")

    flags = "--halt-on-error"
    #flags = "-file-line-error --shell-escape -halt-on-error -interaction nonstopmode -output-directory"

    env = "export max_print_line=1000 ; export TEXINPUTS=${KLAMMERTEXT_HOME}/sks//: ;"
    command = f"{env} cd {dirname} ; {latex_command} {flags} {basename}.tex {remove_log}"
    #print(command)
    result = os.system(command)

    if result != 0:
        os.system(f"tail -n 20 {log_file}")
        msg = f"Error in LaTeX processing.  See file {os.path.relpath(log_file)}"
        #print(f"Error in LaTeX processing.  See file {os.path.relpath(log_file)}")
        raise Exception(msg)

    # No error; is repetition necessary for links, etc?  Check log for this.
    # result = os.system(command)
    # print(f"Wrote {os.path.relpath(pdf_file)}")
    if twice:
        result = os.system(command)

    aux_files = 'aux out toc'.split()    
    if verbose_level < 2:
        aux_files += 'tex log'.split()
    for unused_ext in aux_files:
        os.system('rm -rf {}/{}.{}'.format(dirname, basename, unused_ext))


# Emitted by @vspace.txt (sks/block/block.k), one marker per line of space.
# An @eval result consisting only of whitespace is trimmed away by the
# Klammermachine, so vertical space must travel as markers and become
# newlines here, after blank-line runs have been normalized.
vspace_marker = "__VSPACE__"

def justify_blocks(text, K=None):
    delim = '__DIVIDE__'
    text = re.sub("\n\n+", delim, text)
    result = ""
    for par in text.split(delim):
        stripped = par.strip()
        n = stripped.count(vspace_marker)
        if n and stripped == vspace_marker * n:
            # A paragraph of only @vspace markers: n blank lines in addition
            # to the normal paragraph separation.
            result += "\n" * n
            continue
        if par and par[0] not in {' ', '['}:
            par = "\n".join(textwrap.wrap(par, width=80))
        result += par + "\n\n"
    return result.replace(vspace_marker, "\n")
        
            

