# IMPORT
import os

from flask import Flask, render_template, request, url_for, redirect, jsonify, abort, send_from_directory
import markdown
import subprocess
import frontmatter
from datetime import datetime
import json


# FUNCTIONS

def list_files(folder, remove_ext=False):
    ''' Read all the functions in a folder '''
    names = []
    for entry in os.scandir(folder):
        # add to the list only proper files
        if entry.is_file(follow_symlinks=False):
            # remove the extension from the filename
            n = os.path.splitext(entry.name)[0]
            if remove_ext:
                n = entry.name
            names.append(n)
    return names


def list_folders(folder):
    ''' Return all the folders in a folder '''
    names = []
    for entry in os.scandir(folder):
        # add to the list only proper files
        if not entry.name.startswith('.') and entry.is_dir():
            # remove the extension from the filename
            names.append(entry.name)
    return names


def get_md_contents(filename, directory='./contents'):
    ''' Return contents from a filename as frontmatter handler '''
    with open(f"{directory}/{filename}", "r") as f:
        metadata, content = frontmatter.parse(f.read())
        html_content = markdown.markdown(content, extensions=[
                                         'markdown.extensions.attr_list', 'markdown.extensions.codehilite', 'markdown.extensions.fenced_code'])
    return metadata, html_content


def render_home():
    print('Rendering home...')
    with open('/home/kamo/public_html/render.html', 'w') as f:
        # get the basic info of the website from the /contents/home.md file
        meta, content = get_md_contents("home.md")
        projects_list = []
        for project in list_folders("./projects"):
            project_info = get_md_contents(f"{project}.md",
                                        f"./{projects}/{project}")[0]
            project_date = datetime.strptime(project_info['date'], '%d/%m/%Y')
            project_info['date'] = datetime.strftime(project_date, '%d %b, %y')
            project_info['categories'].sort()

            project_info['slug'] = project
            projects_list.append(project_info)

        projects_list.sort(reverse=True, key=lambda project: datetime.strptime(
            project['date'], '%d %b, %y'))

        # get the list of the projects, the functions, and the corpora
        home = {
            **meta,
            "content": content,
            "projects": projects_list
        }
        f.write(render_template("home.html", **home))
        print('Rendered!')


# FLASK APP

class PrefixMiddleware(object):
    def __init__(self, app, prefix=""):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):
    
        if environ["PATH_INFO"].startswith(self.prefix):
            environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix) :]
            environ["SCRIPT_NAME"] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response("404", [("Content-Type", "text/plain")])
            return ["This url does not belong to the app.".encode()]



projects = 'projects'

# create flask application
app = Flask(__name__)
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/soupboat/~kamo')

# Homepage
@app.route("/")
def home_page():
    return send_from_directory(app.root_path, 'render.html')


# For generic pages we can include a common template and change only the contents
@app.route("/<slug>/")
def dynamic_page(slug=None):
    # meta is a dictionary that contains all the attributes in the markdown file (ex: title, description, soup, etc)
    # content is the body of the md file aka the text content
    # in this way we can access those frontmatter attributes in jinja simply using the variables title, description, soup, etc
    meta, content = get_md_contents(f"{slug}.md")
    return render_template("page.html", **meta, content=content)


# Single project
@app.route("/projects/<project>/")
def p_info(project=None):
    meta, content = get_md_contents(f"{project}.md",
                                    f"./{projects}/{project}")
    template = 'project.html'
    if 'template' in meta:
        template = meta['template']
    return render_template(template, **meta, content=content)


@app.route('/projects/<project>/<path:filename>')
def sendStaticFiles(project, filename):
    return send_from_directory(app.root_path + f'/projects/{project}/', filename, conditional=True)


@app.route('/hook/', methods=['GET', 'POST'])
def pull():
    if request.method == 'POST':
        subprocess.call(['sh', '/home/kamo/public_html/update.sh'])

        print('Request for rendering')
        render_home()

        with open('/home/kamo/public_html/log.txt', 'a') as f:
            f.write(request.form['payload'])
            print(request.form['payload'])

        return 'Updated'
    return 'GET method not supported'


@app.route('/api/render/')
def render():
    print('Request for rendering')
    render_home()
    return redirect(url_for('home_page'))



# RUN
app.run(port="3132")
