#!/usr/bin/env python

import os
import uuid
#from datetime import datetime
#import pytz
from flask import Flask, url_for, render_template, send_from_directory, jsonify, make_response
from flaskext.markdown import Markdown
import markdown
import markdown.extensions.fenced_code
import markdown.extensions.codehilite
import markdown.extensions.toc
from markdown.extensions.toc import TocExtension
from pygments.formatters import HtmlFormatter

app = Flask(__name__)
Markdown(app)

def make_tree(path="templates/content"):
    if '/' in path:
        tree = dict(name=path, children=[], type="directory")
    else:
        pass
    try: lst = os.listdir(path)
    except OSError:
        pass #ignore errors
    else:
        lst.sort()
        for name in lst:
            fn = os.path.join(path, name)
            if os.path.isdir(fn) and not fn.endswith(".git"):
                tree['children'].append(make_tree(fn))
            else:
                if fn.endswith('.md') and not name == "README.md":
                    tree['children'].append(dict(name=fn))
    return tree

def cut_path_tree(tree, subdir, file_ending):
    for key, val in tree.items():
        if isinstance(val, list):
            for item in val:
                item["name"] = item["name"][len(subdir):]
                if item["name"].endswith(file_ending):
                    item["name"] = item["name"][:-len(file_ending)]
                if isinstance(item, dict):
                    cut_path_tree(item, subdir, file_ending)
    return tree

def cut_filetype_tree(tree, filetype):
    for key, val in tree.items():
        if isinstance(val, list):
            for item in val:
                if item["name"].endswith(filetype):
                    item["name"] = item["name"][:-len(filetype)]
                    if isinstance(item, dict):
                        cut_filetype_tree(item, filetype)
    return tree

def list_files(path):
    doc_files = []
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(".md") and not ".git" in root:
                doc_files.append(os.path.join(root,file))
    return doc_files
#
#def dir_structure():
#    for root, dirs, files in os.walk("./templates/content"):
#        if len(files) != 0:
#            print(root.split('/')[3:],  [file[:-3] for file in files if file.endswith('.md')])
#
#def test_def():
#    for i,line in enumerate(l):
#        if len(line[0]) > 0:
#            dic[str(line[0][-1])] = line[-1]
#            result = {}
#            curr = result
#            for p in line[0]:
#                curr = curr.setdefault(p, {})
#def other_test_def():
#    for root, dirs, files in os.walk("templates/content"):
#    #print(root[18:].split('/')[0])
##    print(root, files)
#        key = root[18:].split('/')[0]
#        d[key] = [file[:-3] for file in files]

def build_index(path, file_ending):
    searchable = dict(index=[]) 
    file_list = list_files(path) 
    for item in file_list:
        if item.endswith(file_ending):
            with open(item, 'r') as _f:
                data = _f.readlines()
                data[0] = data[0].strip('# \n')
                #searchable[data[0]] = [''.join(data), item[len(path):-len(file_ending)]]
                searchable["index"].append(dict(uri=item[len(path):-len(file_ending)] + '.html', title=data[0],tags=[],content=''.join(data), description=""))
                #searchable[str(uuid.uuid1())] = (dict(href=item[len(path):-len(file_ending)], title=data[0],tags=[],content=''.join(data)))
        if isinstance(item, dict):
           build_index(item)
    return searchable

@app.route('/index.json')
def index():
    searchable = build_index("templates/content", ".md")
    #searchable = dict(index=[ dict(title="Smp_000020", uri="/geneexp/sm/Smp_000020.1/",content="bifunctional protein NCOAT", tags=[], description=""), dict(title="Smp_000030",uri="/geneexp/sm/Smp_000030.1/",content="26s proteasome regulatory particle subunit", tags=[], description="")])
    response = make_response(searchable)
    response.headers["Content-Type"] = "application/json"
    #response.headers["Content-Encoding"] = "gzip"
    response.cache_control.max_age = 420
    return response

@app.route('/', defaults={'path': 'README'})
@app.route('/<path:path>.html')
def content(path="README"):
    with open(os.path.join(app.root_path, f'templates/content/{path}.md'), "r") as _f:
        md_file = _f.read()
        if not md_file.startswith("[TOC]"):
            md_file = "[TOC]\n" + md_file
    md_template_string = markdown.markdown(md_file, extensions=["fenced_code", "codehilite", "toc", TocExtension(toc_class="column column-3", title=""), "mdx_math"],
            extension_configs={"mdx_math": {"enable_dollar_delimiter": True}})
    formatter = HtmlFormatter(style="material", full=True, cssclass="codehilite")
    css_string = formatter.get_style_defs()
    md_css_string = "<style>" + css_string + "</style>"
    md_template = md_css_string + md_template_string
    #return md_templateresponse = make_response(searchable)
    res = render_template("documentation.html", md_doc=md_template, tree=
            cut_path_tree(
            make_tree("templates/content"), "templates/content", ".md")
            )
    response = make_response(res)
    response.headers["Content-Type"]: "text/html; charset=utf-8"
    return response


#@app.route('/blog/<blog_item>/index.html')
#def blog(blog_item, _date=meta_data):
#    return render_template(f"blog/{blog_item}/index.html", _date=meta_data[blog_item], )

#@app.route("/about.html")
#def about():
#    return render_template("about.html")
#
#@app.route("/contact.html")
#def contact():
#    return render_template("contact.html")


@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')

#@app.errorhandler(404)
#def page_not_found(_error):
#    return render_template("/status_code/404.html"), 404
#
#@app.errorhandler(400)
#def bad_request(_error):
#    return render_template("/status_code/400.html"), 400
#
#@app.errorhandler(500)
#def internal_server_error(_error):
#    return render_template("/status_code/500.html"), 500

with app.test_request_context():
    #print(url_for("content"))
    #print(url_for("about"))
#    print(url_for("contact"))
    #print(url_for("rss"))
    #print(url_for("static", filename="stylesheet.css"))
    #print(meta_data)
    print(url_for("content", md_file="enumeration/windows/bloodhound"))
