#! /usr/bin/env python

# -*- coding: utf-8 -*-

import os, sys, imp, xmlrpclib

from werkzeug import script
from werkzeug.serving import run_simple

from glashammer.version import glashammer_version


def _get_app(modulepath, application_factory_name):

    if not modulepath:
        script.fail('Must provide a module path')
    else:
        modulepath = os.path.abspath(modulepath)

    filename = os.path.basename(modulepath)
    modulename = os.path.splitext(filename)[0]
    dirpath = os.path.dirname(modulepath)

    mfile, mpath, mdesc = imp.find_module(modulename, [dirpath])

    mod = imp.load_module('gh_runner', mfile, mpath, mdesc)

    mfile.close()

    if application_factory_name:
        factory = getattr(mod, application_factory_name, None)
        if factory is None:
            script.fail('Application factory %s not found' %
                        application_factory_name)
        app = factory()
        return app
    else:
        fail('Application factory name must be provided')




def action_run(modulepath='',
               application_factory_name='create_app',
               hostname=('h', 'localhost'), port=('p', 6060),
               reloader=True, debugger=True,
               evalex=True, threaded=False, processes=1):
    """
    Run a WSGI Debug server with an application

    gh-admin runserver <modulepath> [application_factory_name] [options]

    Modulepath is the path to a Python module which contains the callable
    named in the application_factory_name variable. This callable is called
    and expects to receive a WSGI application (eg a GlashammerApplication)
    instance.
    """
    app = _get_app(modulepath, application_factory_name)
    run_simple(hostname, port, app, reloader, debugger, evalex,
                None, 1, threaded, processes)


def action_init(modulepath='', init_function_name='init_app'):
    """
    Run the application's initialization script. This is one time to "install"
    the application.
    """
    _get_app(modulepath, init_function_name)


def action_staticaliases(modulepath='',
                         application_factory_name='create_app'):
    """
    Generate a list of static aliases for insertion into your web server
    config.

    gh-admin staticaliases <modulepath> [application_factory_name]

    Modulepath is the path to a Python module which contains the callable
    named in the application_factory_name variable. This callable is called
    and expects to receive a WSGI application (eg a GlashammerApplication)
    instance.
    """
    app = _get_app(modulepath, application_factory_name)
    for url, path in app.shared_export_map.items():
        print 'Alias %s %s' % (url, path)


def action_endpoints(modulepath='',
                     application_factory_name='create_app'):
    """
    Generate a list of endpoints and urls for the application.

    Modulepath is the path to a Python module which contains the callable
    named in the application_factory_name variable. This callable is called
    and expects to receive a WSGI application (eg a GlashammerApplication)
    instance.
    """
    print
    print 'Generating list of endpoints and urls...'
    print
    app = _get_app(modulepath, application_factory_name)
    print 'Endpoint'.ljust(30) + 'URL Rule'
    print '-' * 75
    for rule in app.map.iter_rules():
        print rule.endpoint.ljust(30) + rule.rule
    print '-' * 75


def action_version():
    """
    Print the version of Glashammer and exit.
    """
    print 'Glashammer, version %s' % glashammer_version


def action_checkversion(upgrade=False):
    """
    Check the installed version against the latest at PyPi.

    If --upgrade is passed, glashammer will attempt to upgrade
    from PyPi.
    """
    server = xmlrpclib.Server('http://pypi.python.org/pypi')
    latest = server.package_releases('Glashammer')[0]
    print 'Installed version:\t\t%s' % glashammer_version
    print 'Latest PyPi version:\t\t%s' % latest
    print '--------'
    if latest == glashammer_version:
        print 'The latest version of Glashammer is installed.'
    else:
        if upgrade:
            print 'Upgrading...'
            os.system('easy_install Glashammer==%s' % latest)
        else:
            print 'Update available. "easy_install -U Glashammer" to upgrade.'


def action_quickstart():
    """
    Create a quickstart application
    """
    name = raw_input('Name of project directory? ').strip()
    if not name:
        print 'Must give a project name.'
        exit(1)
    module = raw_input('Name of main module? (main.py) ').strip()
    if not module:
        module = 'main.py'

    os.mkdir(name)
    os.mkdir(os.path.join(name, 'templates'))
    os.mkdir(os.path.join(name, 'shared'))

    module_content = """# -*- coding: utf-8 -*-
from os.path import dirname

from glashammer import make_app, run_very_simple, sibpath

TEMPLATES_DIRECTORY = sibpath(__file__, 'templates')
SHARED_DIRECTORY = sibpath(__file__, 'shared')

# Main application setup
def setup(app):
    app.add_template_searchpath(TEMPLATES_DIRECTORY)
    app.add_shared('main', SHARED_DIRECTORY)

# Hook for gh-admin
def create_app():
    app =  make_app(setup, dirname(__file__))
    return app

if __name__ == '__main__':
    app = create_app()
    run_very_simple(app)

"""
    f = open(os.path.join(name, module), 'w')
    f.write(module_content)




def action_dependencies():
    """
    Check the required dependencies are available
    """
    print 'Checking dependencies'

    print 'Werkzeug...\t\t',

    try:
        import werkzeug
        print 'Installed'
    except ImportError:
        print 'Missing! "easy_install Werkzeug" to fix.'

    print 'Jinja2...\t\t',
    try:
        import jinja2
        print 'Installed'
    except ImportError:
        print 'Missing! "easy_install Jinja2" to fix.'

    print 'WTForms...\t\t',
    try:
        import wtforms
        print 'Installed'
    except ImportError:
        print 'Missing! "easy_install WTForms" to fix.'



if __name__ == '__main__':
    exit(script.run())

