#!/usr/bin/env python3
#
# update
#
# The 'update' git hook for verifying the publish branch
#
"""
To use this, copy this file into the 'hooks' directory in your server's git
repository. Also, add a configuration file to tell aberdeen where to send
the generated blog posts.
"""

import sys, os

from configparser import ConfigParser

dirname = os.path.basename(os.path.dirname(os.path.abspath(__file__))).strip()

# expect configuration to be in same directory
if dirname != 'hooks':
    print(("ERROR: "
           "The update hook is not in a directory named 'hooks', rather it's in"
           " \"%s\". Aborting." % (dirname)),
           file=sys.stderr)
    sys.exit(1)

if not os.path.exists("hooks/aberdeen.cfg"):
    print(("ERROR: "
           "No aberdeen configuration file found. Please create one and add to "
           "the server's 'hooks' directory. Aborting."),
           file=sys.stderr)
    sys.exit(1)

try:
    cfg_file = open("hooks/aberdeen.cfg", 'r')
except Exception as err:
    print(("ERROR: "
           "Could not open aberdeen configuration file."),
           err, file=sys.stderr)
    sys.exit(1)

config = ConfigParser()
config.read_file(cfg_file)

cfg_file.close()

cfg_aberdeen = config["aberdeen"]
cfg_database = config["database"]

if 'venv' in cfg_aberdeen:
    p = os.path.join(cfg_aberdeen['venv'], 'lib', 'python3.4', 'site-packages')
    sys.path.insert(1, p)

import aberdeen

branch, old_commit, new_commit = sys.argv[1:4]

if branch.split('/')[-1] == cfg_aberdeen['publish_branch']:
    print("===update===")
    print("Pushing update to publish branch. Inspecting files:")
    import aberdeen
    from markdown import Markdown
    from termcolor2 import c

    markdown_suffixes = ['.md','.markdown']
    html_suffixes = ['.html','.htm']

    # Gets filename of changed files
    diff_cmd = "diff --name-only %s %s -- *.md" % (old_commit, new_commit)
    changed_filenames = aberdeen.call_git(diff_cmd).strip()

    # Gets the filename and 'blob id' of files which have been changed
    ls_tree_cmd = 'ls-tree --full-name -r %s' % (new_commit)
    all_files = aberdeen.call_git(ls_tree_cmd).split('\n')[:-1]

    files = [
        {'name': line.split()[3], 'blob': line.split()[2]}
        for line in all_files
    ]

    files_changed = [
        {'name': line.split()[3], 'blob': line.split()[2]}
        for line in all_files if line.split('\t')[-1] in changed_filenames
    ]

    # We must force the use of utf so we get cool ✓ characters!
    if sys.getdefaultencoding() is not 'utf-8':
        import codecs
        sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())

    errors = []
    for file in files_changed:
        filename = file['name']
        blob_id = file['blob']
        print("Testing", filename, end=' ')
        cat_cmd = "cat-file blob " + blob_id
        contents = aberdeen.call_git(cat_cmd.split())
        if any(map(filename.endswith, markdown_suffixes)):
            try:
                aberdeen.generate_from_markdown(contents)
                print(c('✓').green)
            except Exception as err:
                print(c('✗').red)
                err = "  %s\n%s\n" % (file['name'], str(err))
                errors.append(err)

    if errors:
        print("Errors:")
        print("\n".join(errors))
        print(("** The commit was NOT accepted. Please fix the issues and "
               "push the changes again.\n"))
        sys.exit(1)

    print ("No Errors found, continuing.")

    posts = []
    for file in files:
        filename = file['name']
        blob_id = file['blob']
        if any(map(filename.endswith, markdown_suffixes)):
            contents = aberdeen.call_git(['cat-file', 'blob', blob_id])
            posts.append(aberdeen.generate_from_markdown(contents))
        elif any(map(filename.endswith, html_suffixes)):
            pass

    print("[update] Generated %d posts" % (len(posts)))
    try:
        aberdeen.upload_posts_to_database(posts, cfg_database)
    except Exception as err:
        error = c("Error:").red
        print("[update] "+error+" Could not upload files to database.")
        print("[update]", err)
        sys.exit(1)

    print("[update] :-) Successfully uploaded posts to database ❁")
