#!/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6

########################################################
##### Markdown to HTML Converter for Documentation #####
#####                by Chris Pyles                #####
########################################################

import markdown2 as md
import sys
import glob
import re
import argparse
import yaml
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
from md2html.pygments_style import Monokai

# import executables from this directory
from md2html.converter_html import *
import md2html.syntax_highlighting as sh

# create CLI argument parser and extract arguments
parser = argparse.ArgumentParser(description="convert Markdown to HTML")
parser.add_argument("-s", "--site-info", dest="site", help="add metadata to the HTML files")
parser.add_argument("-n", "--nav", dest="nav", help="add a YAML file to use for navigation menu")
parser.add_argument(dest="files", nargs=argparse.REMAINDER, help="files to be converted to HTML")
namespace = vars(parser.parse_args())

# determine whether or not navigation menu & metadata need to be added
has_nav = namespace["nav"] != None or namespace["site"] != None
has_meta = namespace["site"] != None

# create HTML segment of metadata
if has_meta:
	with open(namespace["site"]) as f:
		meta = yaml.safe_load(f)
	new_head = "<head>\n\t<title>{}</title>\n".format(meta["title"])
	if "description" in meta:
		new_head += "\t<meta name=\"description\" content=\"{}\">\n".format(meta["description"])
	if "author" in meta:
		new_head += "\t<meta name=\"author\" content=\"{}\">\n".format(meta["author"])
	new_head += "\t<!-- <link"

# create HTML segment for navigation menu
if has_nav:
	if has_meta:
		nav = meta["navigation"]
	else:
		with open(namespace["nav"]) as f:
			nav = yaml.safe_load(f)

	nav_html = """<body><nav class=\"navbar navbar-expand-md navbar-light bg-light\">
	
	<a class=\"navbar-brand\" href=\"#\">""" + nav["nav_title"] + """</a>
	
	<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    	<span class="navbar-toggler-icon"></span>
 	</button>

 	<div class="collapse navbar-collapse" id="navbarSupportedContent">
 		<ul class="navbar-nav ml-auto">
	"""

	for link in nav["links"]:
		nav_html += "\t\t\t<li class=\"nav-item active\"><a class=\"nav-link\" href=\"" + link["url"] + "\">" + link["title"] + "</a></li>\n"
		if link["url"] == "index.html":
			home_page_name = link["title"]

	nav_html += "</ul></div></nav>\n\n<div class=\"container\" id=\"body\">\n"

# define regexes for replacing MD and adding sections
div_regex = r"\<div class=\"container\" id=\"body\"\>\n\<\/div\>"
table_regex = r"\<p\>\|(.*\|)+\n\|(\-+\|)+\n(\|.*\|\n)*\|.*\|\<\/p\>"
code_regex = r"\<p\>\<code\>(.*\n)*?\<\/code\>\<\/p\>"
head_regex = r"\<head\>\n\t\<!-- \<link"
# nav_regex = r"\<body\>\<nav"

# utils for replacing regexes above with new HTML code
def add_in_head(html):
	"""
	Substitues head_regex for new head metadata
	"""
	return re.sub(head_regex, new_head, html)

def sub_in_html(html_template, html):
	"""
	Substitutes an empty <div></div> in template for the converted HTML
	"""
	return re.sub(div_regex, html, html_template)

def add_in_nav_html(html):
	"""
	Adds in navigation menu
	"""
	return re.sub(r"\<body\>\<div class=\"container\" id=\"body\"\>", nav_html, html)

def add_code_class(markdown):
	"""
	Uses pygments to add syntax highlighting to code
	"""
	return sh.run_lexer(markdown)

def replace_table(table):
	"""
	Generates HTML tables from MD tables
	"""
	html = "<table class=\"table\"><tr><th scope=\"col\">"
	table = table[3:-4]
	lines = table.split("\n")
	headers = lines[0][2:-2].split(" | ")
	for h in headers:
	    html += h + "</th><th scope=\"col\">"
	html = html[:-16]
	html += "</tr><tr>"
	for line in lines[2:]:
	    data = line[2:-2].split(" | ")
	    html += "<td>"
	    for d in data:
	        html += d + "</td><td>"
	    html = html[:-4]
	    html += "</tr><tr>"
	html = html[:-4]
	html += "</table>"
	return html

# # construct the HTML file if no nav
# if not has_nav:

# 	# no CLI args given
# 	if len(sys.argv) == 1:
# 		print("Please enter a filename.")
# 		sys.exit()

# 	# * wildcard found
# 	elif len(sys.argv) == 2 and "*" in sys.argv[1]:
# 		file_names = glob.glob(sys.argv[1])

# 	# use the CLI args as filenames
# 	else:
# 		file_names = sys.argv[1:]

# 	# construct the HTML stirng
# 	for file_name in file_names:
# 		markdowner = md.Markdown()

# 		# get MD contents for syntax highlighting
# 		with open(file_name) as f:
# 			file_md = f.read()

# 		# get HTML for MD code
# 		code_html = []
# 		match = re.search(sh.code_regex, file_md)
# 		while match != None:
# 			code = match[0]
# 			code = add_code_class(code)
# 			code_html += [code]
# 			file_md = re.sub(sh.code_regex, "", file_md, count=1)
# 			match = re.search(sh.code_regex, file_md)

# 		# open the MD file and convert to HTML
# 		with open(file_name) as f:
# 			html = "<div class=\"container\" id=\"body\">\n" + markdowner.convert(f.read())

# 		# replace MD tables with HTML tables
# 		match = re.search(table_regex, html)
# 		while match != None:
# 			html = re.sub(table_regex, replace_table(match[0]), html)
# 			match = re.search(table_regex, html)

# 		# add back in the code with syntax highlighting
# 		for code in code_html:
# 			html = re.sub(code_regex, code, html, count=1)

# 		# change block code to have HTML class "code"
# 		match = re.search(code_regex, html)
# 		while match != None:
# 			html = add_code_class(html)
# 			match = re.search(code_regex, html)

# 		html += "\n</div>"

# 		# substitute in new HTML
# 		html = sub_in_html(html_template, html)

# 		# write the HTML file
# 		with open(file_name[:-2] + "html", "w+") as f:
# 			f.write(html)

# construct HTML with nav
# else:
# * wildcard
if len(sys.argv) == 4 and "*" in sys.argv[3]:
	file_names = glob.glob(sys.argv[3])
else:
	file_names = sys.argv[3:]

for file_name in file_names:
	markdowner = md.Markdown()

	# get MD contents for syntax highlighting
	with open(file_name) as f:
		file_md = f.read()

	# get HTML for MD code
	code_html = []
	match = re.search(sh.code_regex, file_md)
	while match != None:
		code = match[0]
		code = add_code_class(code)
		code_html += [code]
		file_md = re.sub(sh.code_regex, "", file_md, count=1)
		match = re.search(sh.code_regex, file_md)

	# open the MD file and convert to HTML
	with open(file_name) as f:
		html = "<div class=\"container\" id=\"body\">\n" + markdowner.convert(f.read())

	# replace MD tables with HTML tables
	match = re.search(table_regex, html)
	while match != None:
		html = re.sub(table_regex, replace_table(match[0]), html)
		match = re.search(table_regex, html)

	# add back in the code with syntax highlighting
	for code in code_html:
		html = re.sub(code_regex, code, html, count=1)

	html += "\n</div>"

	# substitute in new HTML
	html = sub_in_html(html_template, html)

	# add in navigation menu
	html = add_in_nav_html(html)

	# add in metadata
	if has_meta:
		html = add_in_head(html)

	# # add in top div
	# for link in nav["links"]:
	# 	if link["url"][:-5] + ".md" == file_name:
	# 		page_title = link["title"]
	# 		page_url = link["url"][:-5]

	# try:
	# 	if page_url == "index":
	# 		top_div = f"""<body>
	# 		<div id="top">

	# 		<table id="header"><tr><td style="border: none;">
	# 		<p id="header" style="text-align: left;">
	# 		{home_page_name}
	# 		</p></td><td style="border: none;">
	# 		<p id="header" style="text-align: right; margin-right: 38px; padding-left: 0;">
	# 		{meta["title"]}
	# 		</p></td></tr></table>

	# 		</div>
	# 		<nav>"""
	# 	else:
	# 		top_div = f"""<body>
	# 		<div id="top">

	# 		<table id="header"><tr><td style="border: none;">
	# 		<p id="header" style="text-align: left;">
	# 		<a class="nav" href="index.html">{home_page_name}</a> &nbsp;<span style="font-size: 9pt;">►</span>&nbsp; {page_title}
	# 		</p></td><td style="border: none;">
	# 		<p id="header" style="text-align: right; margin-right: 38px; padding-left: 0;">
	# 		{meta["title"]}
	# 		</p></td></tr></table>

	# 		</div>
	# 		<nav>"""

	# except NameError:
	# 	top_div = f"""<body>
	# 	<div id="top"></div>
	# 	<nav>"""

	# html = re.sub(nav_regex, top_div, html)

	# write the HTML file
	with open(file_name[:-2] + "html", "w+") as f:
		f.write(html)