#!/usr/bin/env python

import bottle
import yaml
import os, io, time, shutil
from distutils.dir_util import copy_tree

# Magic to load YAML in order
from collections import OrderedDict
def ordered_load(stream, Loader = yaml.Loader, object_pairs_hook = OrderedDict):
    class OrderedLoader(Loader):
        pass
    def construct_mapping(loader, node):
        loader.flatten_mapping(node)
        return object_pairs_hook(loader.construct_pairs(node))
    OrderedLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, construct_mapping)
    return yaml.load(stream, OrderedLoader)

# Main functionality
def build(src_dir, dst_dir, config_path, data_path):
    # Print last timestamp
    if os.path.isdir(dst_dir) and os.path.isfile(os.path.join(dst_dir, '.timebuilt')):
        with io.open(os.path.join(dst_dir, '.timebuilt')) as time_file:
            print '\033[93m\r', 'Last built:', time.ctime(float(time_file.read())), '\033[0m'
    # Message
    print '\033[92m\r', 'Building Site', '\033[0m'
    if os.path.isdir(dst_dir):
        shutil.rmtree(dst_dir)
    config = None
    with io.open(config_path) as config_file:
        config = yaml.load(config_file.read())
    for dir_name, sub_dir_list, file_list in os.walk(src_dir):
        os.mkdir(os.path.abspath(dir_name.replace(src_dir, dst_dir + '/')))
        for file_name in file_list:
            file_src = os.path.abspath(os.path.join(dir_name, file_name))
            file_dst = os.path.abspath(os.path.join(dir_name, file_name).replace(src_dir, dst_dir + "/", 1))
            print file_src, file_dst
            file_splt = os.path.splitext(file_dst)
            if file_src == config_path:
                continue
            if file_splt[-1] == '.in':
                with io.open(file_src) as src:
                    with io.open(file_splt[0], 'w') as dst:
                        dst.write(bottle.template(src.read(), **config))
            else:
                shutil.copyfile(file_src, file_dst)


    # Calculate most recent update time
    max_mtime = 0
    for dirname,subdirs,files in os.walk(src_dir):
        for fname in files:
            if fname == '.timebuilt' or fname == '_config.yml':
                continue
            full_path = os.path.join(dirname, fname)
            mtime = os.path.getmtime(full_path)
            if mtime > max_mtime:
                max_mtime = mtime

    with io.open(os.path.join(dst_dir, '.timebuilt'), 'w') as time_file:
        time_file.write(unicode(max_mtime))

    # Copy in data folder
    copy_tree(data_path, dst_dir)

if __name__ == '__main__':
    cur_dir = os.path.abspath(os.path.dirname(__file__))
    build(
        os.path.join(cur_dir, '_template'),
        os.path.join(cur_dir, '_site'),
        os.path.join(src_dir, '_config.yml'),
        os.path.join(cur_dir, '_data')
    )
