#!/usr/bin/env python
""" Nest 1.0

    Controller CLI for Tori
"""

import base64
import zlib

resources = dict()

resources['tori_Makefile'] = zlib.decompress(base64.b64decode('eNqVkFFrgzAUhZ+bX3EpggqrfReEltJuwgYyu0GfJMQrhqmR3Gjx3y/pWje2vixPuScfJ+fc7JQm/WRq1bF8//qe7vbF4Xn7mLB8l+dFtj0+JWS4kWJNgoj9Fp3GSqz40JiYLTYoagX+m5GNNBMclWpglBxe+Af68zNAa2cg1KMUGANwYeSIYOpZ/APbjyzojlBtLxsEGwUqrVpwSe/xRWNN4/s88K6EoS+5QTjX2AGHykGSrmp5c5yND0pDqzSC6o1UHT2AHjpYRmthB9XgMvIZmzu5xSw2XpCd0vBSCnXUT+AFP7ccMuZ6WZA4EaxW10SWui06jL1gvluCzGRjuk4aibC8OHw1/bY5cyPqf7l8Amggoxc='))
resources['tori_service.xml'] = zlib.decompress(base64.b64decode('eNqzsa/IzVEoSy0qzszPs1Uy1DNQUkjNS85PycxLt1UqLUnTtVCyt+OyycxNTM/MSywBqgLy9FG4AAFmFn0='))
resources['tori_config_dev.xml'] = zlib.decompress(base64.b64decode('eNpdUstOwzAQvOcrjI+VEsONg2MOgMQZvsB1Nq2RG0e7NiBV/Xc2cWhScrF3Zh+zE+unn1MQX4Dk49DKh+ZeChhc7PxwaGVOff0on0yl7TgG72ziLFMJ/jQBclkJZqCDfT6YhBm0KveVGyMmcz6L6RSXi1YzsPIEDiEZrZbLytzVtdCAGNGwhuYb9o2LQ8IYAmDzOhHP11irkinqelGptjJ1JhCErpUEKfGG1HxSHKRaaIw5Af0b/gK9zSGJj8TbO/EOFDM6oOuMUrrAwnfcfU6VIsTi2IqMNiVABlRB1G4nhbPuCK3sbSD40zI3XRed244Ye88BVwRL1Eo2dLAnYEO3nrzFE2wnHadY3WjtPIKblG3SpOiA2JRF8U2ZVltr5l/vHZjlbPgJFaMnsNLq5rFUv8NXvow='))
resources['tori_controller.py'] = zlib.decompress(base64.b64decode('eNpFi0EKgzAQRfc5xd8lQskBCl114zVEJ1WYychkduLdq1TsW73/4BdTgastedTqpsxkWGRVc7zvEsLIQ2voVSj9c/cMOJio4EOeGnG50sk5s1GdyFKcj2eeXTg+UAchvBC37af7HrsvodIs6g=='))
resources['tori_template_home.html'] = zlib.decompress(base64.b64decode('eNqVU01v2zAMvedXcL7sskhzdhkKx9hpwIAdC+xYKDZrK5FFT6SbGkX/e+nESfqFAtVBtKjHR+qRLr7UVMnYI7TShXJRnAy6Wk2H4qBqXWKUdTbI7fJnpm7xErB8eIDoOoTHR1hCJIGkQSOMKIU9IhYFV8n3ApyqdWat27p70xA1AV3v2VTUHXw2+A3b7f8B02hXJjf5fDCdj2bLWVnYI9Mbys7dV3U0GyJhSa6fDhPt2WF/mJX5brd8cb3HGnzcQZvw9jOkFb9mVU+mOoR1xjIG5BZRJsXsLOiG6lFN7e+gCo55nVUUxfmISWGg6/ldor0W+QIcltwt89UJ3OblX5SvDA2qJKTd2FPaQU0RjSbNZ1h/tNP612KEkQZwCcFHhQ4b+Qa9toQRGgK6wwTSot5UQ4danXiKfHVksjNVMYQLp6pXFm6WrxXp+cpaoeTNNBLKpVRsKDUWow1OkEU1joMLVusWH5sbFpcEazPNX1Zeayz8Tjpd03MK67RVmuPjhL5zjY+Haj/I+37CP5fYl9kKe3rocxEpgeMdvH3z3otgOgwLtz7ROOx8Vv46f0/kQBGuZ+ArUa32ujzui7Ppp20eHHv4P58AMvk3vg=='))
resources['flask_server.py'] = zlib.decompress(base64.b64decode('eNplUMtqxDAMvPsrRC52liXteSHQU7+gd+ESuWsaP3BsKAT/exU1SwuVD5ZmpBkkV1IAt9rtE3zIqVR4PQrl/uGF4kIFK4W82kpgtxNSyuaM0QaCGfS+g6S9ayEYE0WD0oI4KvXC+FRSq2SGp2FUCznwLPVlxpsCjkK1lXjqGy3cdK9h1Vc4jR6eLOcdPMRhnmFADNZHxOFHLOXqU9x4Zpf6CH1PW9U3Tp4nefr6yy303j6YfCuN/sDHFY4R3lAO0rtwXcknK7VoLpfTb/wGV5Voqg=='))
resources['tori_settings.json'] = zlib.decompress(base64.b64decode('eNpljkEOwyAMBO95BeJcwT1/6COchCZIGEeYHCrkvxdIpQrVl7Vmd2WXSdXR7Jg9RT2r0kGHawDminSm5M03YpI7iX1Fb4MOmzy76MeveUICbNUiHcrt6W0ZLyBE2F3igd5J94Ir5D+jm1cK7S2kuNO2zNYGWiEcxNmWoiKgUyJ66Mk0bjLJB3rkQJg='))
resources['tori_server.py'] = zlib.decompress(base64.b64decode('eNpNykEKgCAQQNH9nGKghRVo2whadBSxlAF1xKbo+NEqt//9DvWo0fFOOSx4idfzVwB85YTClYwtJZKzQpyRUuEquP0JoPW1pV45zp7CtB+3eVJUQ/uaU2yVfoAXJYwstQ=='))
resources['flask_template_index.html'] = zlib.decompress(base64.b64decode('eNqVkj1z2zAMhnf/ClRLl5iwnKWXkzVm6t6ZpmCJNkUoJJREl8t/LxTJ+Wi7lANxBF8+BF+w+tawk2kg6KQP9aa6BrKNhp7EgutsyiSHYpTT9kehafESqH55gWh7gtdX2EJkgaSHJphIKlwUmyq75AeBnNyhQLRn+2xa5jaQHXw2jvu3HAZ/zHh+GClNuDelKdeF6X0051zUFS6kv5C9fXZNNEdmyZLsMC9m7HsCb83e7PCcP1L/ogYfL9AlOv0P1OU/qZop1IdwKLJMgXJHJLNjuBp65GbS0PhHcMHmfCgcR7E+UlIZ6Pi8l/hJi/wiDtvcb8v9VdyV9U+S7xlaUktYu/HE6QINRzJ6abnKhiXO41dHESYewSYCH1U6HuUGBm1JJmgZ+JESSEe648aetDrxHPPdQsIVVY3hg6nu1ZVd7etEhjvEk1Z8MQM7ZsOpRaVl3Jlyhw+jd5csNgkW9f0sq9BqLxSy3nFlV6hvr5d58x6GeVqNxLf/+hu1OOXX'))


import argparse
import sys
from tori.cli.console import Console as BaseConsole

class Console(BaseConsole):
    def __init__(self):
        self.namespace = 'Nest'
        self._commands = {}

    def enable(self, id, cls):
        self._commands[id] = cls

    def show_console_usage(self):
        self.output('USAGE: {} <command>'.format(self.namespace or sys.argv[0]))
        self.output('\nAvailable commands:')

        command_desc_map = {}
        longest_cmd_length = 0

        for id in self._commands:
            if longest_cmd_length < len(id):
                longest_cmd_length = len(id)

            command_class = self._commands[id]
            command_doc   = command_class.__doc__ or '(internal command)'

            command_desc_map[id] = command_doc.strip()

        format_string = '  {:<%d}    {}' % (longest_cmd_length + 4)

        for id in command_desc_map:
            self.output(format_string.format(id, command_desc_map[id]))

    def run(self):
        if len(sys.argv) == 1:
            self.show_console_usage()
            sys.exit(0)

        command_id = sys.argv[1]

        if command_id not in self._commands:
            self.show_console_usage()
            sys.exit(1)

        command  = self._commands[command_id]()

        parser         = argparse.ArgumentParser(description='Console')
        subparsers     = parser.add_subparsers()
        command_parser = subparsers.add_parser(command_id, description=command.__class__.__doc__.strip())

        command.define_arguments(command_parser)
        command.execute(parser.parse_args())

# flask.app.create
import os
from tori.cli.command import Command
from jinja2 import Template

class FlaskCreateSkeletonApp(Command):
    """ Create a skeleton app """
    def define_arguments(self, argument_parser):
        argument_parser.add_argument('name', help='The name of the app and the app module (e.g. piano_and_violin)')
        argument_parser.add_argument('-p', '--port', type=int, help='the initial port number', default=8000)
        argument_parser.add_argument('-f', '--force', action='store_true', help='force / override the existing files', default=8000)
        argument_parser.add_argument('-o', '--output', help='the base output path (default: the current directory)', default='')

    def execute(self, args):
        self.app_name   = args.name
        self.force_mode = args.force
        self.base_path  = args.output
        self.init_port  = args.port

        if self.base_path:
            if not os.path.exists(self.base_path):
                os.makedirs(self.base_path)

            os.chdir(self.base_path)

        self._generate_directories([
            'static/js',
            'static/css',
            'static/scss',
            'static/image',
            'templates'
        ])

        self._copy_resource('Makefile', 'tori_Makefile')
        self._copy_resource('templates/index.html', 'flask_template_index.html')
        self._write_resource('server.py', 'flask_server.py')

    def _copy_resource(self, where, origin):
        content = resources[origin]

        self._write(where, content)

    def _write_resource(self, where, template_name, **contexts):
        template = Template(resources[template_name])

        contexts.update({
            'name': self.app_name,
            'port': self.init_port
        })

        self._write(where, template.render(**contexts))

    def _write(self, where, content):
        if os.path.exists(where):
            if not self.force_mode:
                return

            os.unlink(where)

        with open(where, 'w') as f:
            f.write(content)

    def _generate_directories(self, directories):
        for directory in directories:
            if os.path.exists(directory):
                continue

            os.makedirs(directory)

# tori.app.create
import os
from tori.cli.command import Command
from jinja2 import Template

class ToriCreateSkeletonApp(Command):
    """ Create a skeleton app """
    def define_arguments(self, argument_parser):
        argument_parser.add_argument('name', help='The name of the app and the app module (e.g. piano_and_violin)')
        argument_parser.add_argument('-p', '--port', type=int, help='the initial port number', default=8000)
        argument_parser.add_argument('-f', '--force', action='store_true', help='force / override the existing files', default=8000)
        argument_parser.add_argument('-o', '--output', help='the base output path (default: the current directory)', default='')

    def execute(self, args):
        self.app_name   = args.name
        self.force_mode = args.force
        self.base_path  = args.output
        self.init_port  = args.port

        if self.base_path:
            if not os.path.exists(self.base_path):
                os.makedirs(self.base_path)

            os.chdir(self.base_path)

        self._generate_directories([
            'config',
            'static/js',
            'static/css',
            'static/scss',
            'static/image',
            'templates',
            args.name
        ])

        self._copy_resource('Makefile', 'tori_Makefile')
        self._copy_resource('server.py', 'tori_server.py')
        self._copy_resource('config/service.xml', 'tori_service.xml')
        self._copy_resource('templates/home.html', 'tori_template_home.html')
        self._write_resource('config/dev.xml', 'tori_config_dev.xml')
        self._write_resource('config/settings.json', 'tori_settings.json')
        self._write_resource('{}/controller.py'.format(self.app_name), 'tori_controller.py')
        self._write('{}/__init__.py'.format(self.app_name), '')

    def _copy_resource(self, where, origin):
        content = resources[origin]

        self._write(where, content)

    def _write_resource(self, where, template_name, **contexts):
        template = Template(resources[template_name])

        contexts.update({
            'name': self.app_name,
            'port': self.init_port
        })

        self._write(where, template.render(**contexts))

    def _write(self, where, content):
        if os.path.exists(where):
            os.unlink(where)

        with open(where, 'w') as f:
            f.write(content)

    def _generate_directories(self, directories):
        for directory in directories:
            if os.path.exists(directory):
                continue

            os.makedirs(directory)

modules = dict()

modules['tori.app.create'] = ToriCreateSkeletonApp
modules['flask.app.create'] = FlaskCreateSkeletonApp

if __name__ == '__main__':
    console = Console()

    for id in modules:
        console.enable(id, modules[id])

    console.run()