#!/home/cward/virtenvs/qecamp/bin/python
# -*- coding: utf-8 -*-
# Author: Chris Ward <cward@redhat.com>

'''
'''

import functools
import logging
import os
import shutil
import subprocess

from babel.support import Translations
import click
import ipdb  # NOQA

from comdev.lib import render_template, load_config, get_jinja2_env, dumps
from comdev.lib import expand_path

# Setup console logging; since this is a bin script, grab root
log = logging.getLogger()


def _clean_build(path_build):
    if os.path.exists(path_build):
        log.debug('Cleaning up old builds in {}'.format(path_build))
        shutil.rmtree(path_build)


def _copy_static(path_build, path_static):
    # Copy out all the static files to root of output directory
    for _path in os.listdir(path_static):
        from_path = os.path.join(path_static, _path)
        to_path = os.path.join(path_build, _path)
        if os.path.exists(to_path):
            log.warning('"static" path already exists: {}'.format(to_path))
        else:
            log.debug('Copying "static" to build dir: {}'.format(to_path))
            shutil.copytree(from_path, to_path)


@click.group()
@click.argument('app-name', type=str)
@click.option('--quiet', '-q', is_flag=True, default=False)
@click.option('--debug', '-d', is_flag=True, default=False)
@click.pass_context
def cli(ctx, quiet, debug, app_name):
    if quiet:
        log.setLevel(logging.WARN)
    elif debug:
        log.setLevel(logging.DEBUG)
    else:
        log.setLevel(logging.INFO)

    ctx.obj['app_name'] = app_name


@cli.command('build')
@click.argument('config-dir', type=str, default='./')
@click.option('--relative-urls', is_flag=True, default=False)
@click.pass_context
def build(ctx, config_dir, relative_urls):
    app_name = ctx.obj['app_name']

    config = load_config(app_name, config_dir)
    locales = config['locales'].get()

    paths = config['paths'].get()
    path_templates = expand_path(paths['templates'])
    path_build = expand_path(paths['build'])
    path_static = expand_path(paths['static'])
    path_locale = expand_path(paths['locale'])

    # Clean up the previous build
    _clean_build(path_build)
    _copy_static(path_build, path_static)

    jinja2_env = get_jinja2_env(path_templates)

    # add the ext to the jinja environment
    if relative_urls:
        jinja2_env.filters['url'] = rel_url
        jinja2_env.filters['static'] = functools.partial(rel_url, static=True)
    else:
        jinja2_env.filters['url'] = ext_url
        jinja2_env.filters['static'] = functools.partial(ext_url, static=True)

    # Build all the pages for the site
    templates = config['templates'].get()
    params = {}

    os.environ['PATH_BUILD'] = path_build
    for path in templates:
        for locale in locales:
            os.environ['LOCALE'] = locale
            translations = Translations.load(path_locale, [locale])
            jinja2_env.install_gettext_translations(translations,
                                                    newstyle=True)
            lang = locale.split('_')[0]
            params['lang'] = lang
            content = render_template(
                jinja2_env, path, params, inline_css=False)

            # Save the rendered page to disk
            dest_file = os.path.join(path_build, lang, path)
            dest_path = os.path.dirname(dest_file)
            # create the directory struct where the file will live
            if not os.path.exists(dest_path):
                os.makedirs(dest_path)
            # dump the rendered file
            dumps(content, dest_file)
            assert os.path.exists(dest_file)


def ext_url(path, static=False, lang=None):
    path = path.strip()
    path_build = os.environ['PATH_BUILD']
    locale = os.environ.get('LOCALE', 'en_US')
    lang = lang or locale.split('_')[0]
    if path[0] == '/':
        path = path.lstrip('/')  # path.join only joins if no leading '/'
        if static:
            path = os.path.join(path_build, path)
        else:
            path = os.path.join(path_build, lang, path)
    else:
        path = os.path.join(path_build, path)

    path = 'file://{}'.format(path)
    return path


def rel_url(path, static=False, lang=None):
    path = path.strip()
    locale = os.environ.get('LOCALE', 'en_US')
    lang = lang or locale.split('_')[0]
    if path[0] == '/' and static:
        path = path.lstrip('/')  # path.join only joins if no leading '/'
        path = os.path.join(lang, path)
    new_path = '{}'.format(path)
    return new_path


@cli.command('i18n')
@click.argument('action', nargs=-1)
@click.pass_context
def i18n(ctx, action):
    '''
    Initialize, update and compile gettext i18n strings
    '''

    '''
    Create the folder structure (no whitespace after the commas!)
    > mkdir -pv ./i18n/{en_US,cs_CZ,sk_SK}/LC_MESSAGES/
    > pybabel -v extract -F babel.cfg -o ./i18n/messages.pot ./

    Init/Update
    3.1 Init
    > pybabel init -l en_US -d ./i18n -i ./i18n/messages.pot
    > pybabel init -l cs_CZ -d ./i18n -i ./i18n/messages.pot
    > pybabel init -l sk_SK -d ./i18n -i ./i18n/messages.pot

    3.2 Update
    > pybabel update -l en_US -d ./i18n -i ./i18n/messages.pot
    > pybabel update -l cs_CZ -d ./i18n -i ./i18n/messages.pot
    > pybabel update -l sk_SK -d ./i18n -i ./i18n/messages.pot

    Compile
    > pybabel compile -f -d ./i18n

    What if the strings change? Create a new messages.pot and merge the changes
    > pybabel update -d ./i18n -i ./i18n/messages.pot
    '''

    # These are the languages we want to build for
    languages = ['en_US', 'cs_CZ', 'sk_SK']

    if 'extract' in action:
        cmd = 'pybabel -v extract -F babel.cfg -o ./i18n/messages.pot ./'
        subprocess.run(cmd, shell=True)

    if 'init' in action:
        cmd = 'pybabel init -l {} -d ./i18n -i ./i18n/messages.pot'
        for lang in languages:
            subprocess.run(cmd.format(lang), shell=True)

    if 'update' in action:
        cmd = 'pybabel update -l {} -d ./i18n -i ./i18n/messages.pot'
        for lang in languages:
            subprocess.run(cmd.format(lang), shell=True)

    if 'compile' in action:
        cmd = 'pybabel compile -f -d ./i18n'
        subprocess.run(cmd, shell=True)


@cli.command('serve')
@click.pass_context
def serve(ctx):
    '''
    Launch flask application to serve up the pages dynamically
    '''

    from devconf.flask_app import app
    # FIXME: why doesn't debug info log when running this way?
    app.run(debug=True)


if __name__ == '__main__':
    cli(obj={})
