#!/usr/bin/env python

from collections import namedtuple
import optparse

template = """
#!/usr/bin/env python

import logging

from peewee import *
from peewee import create_model_tables
%(extra_import)s

db = %(engine)s('%(database)s')

class BaseModel(Model):
    class Meta:
        database = db

%(models)s
def main():
    db.create_tables([%(model_names)s], True)
%(logging)s

if __name__ == '__main__':
    main()
""".strip()

model_template = """
class %(model_name)s(BaseModel):
    pass
"""

logging_template = """
logger = logging.getLogger('peewee')
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
"""

class Engine(namedtuple('_Engine', ('engine', 'imports'))):
    def __new__(cls, engine, imports=None):
        return super(Engine, cls).__new__(cls, engine, imports)

    def get_import(self):
        if self.imports:
            return 'from %s import *' % self.imports
        return ''

engine_mapping = {
    'postgres': Engine('PostgresqlDatabase'),
    'postgres_ext': Engine('PostgresqlExtDatabase', 'playhouse.postgres_ext'),
    'sqlite': Engine('SqliteDatabase'),
    'sqlite_ext': Engine('SqliteExtDatabase', 'playhouse.sqlite_ext'),
    'mysql': Engine('MySQLDatabase'),
    'apsw': Engine('APSWDatabase', 'playhouse.apsw_ext'),
    'bdb': Engine('BerkeleyDatabase', 'playhouse.berkeleydb'),
}

def render_models(models, engine, database, logging=False):
    rendered_models = []
    class_names = []

    for model in models:
        class_name = model.strip().title()
        class_names.append(class_name)
        rendered_models.append(model_template % {'model_name': class_name})

    parameters = {
        'database': database,
        'engine': engine.engine,
        'extra_import': engine.get_import(),
        'logging': logging_template if logging else '',
        'models': '\n'.join(rendered_models + ['']),
        'model_names': ', '.join(class_names),
    }

    return template % parameters


if __name__ == '__main__':
    parser = optparse.OptionParser(
        usage='Usage: %prog [options] model1 model2...')
    ao = parser.add_option
    ao('-l', '--logging', dest='logging', action='store_true')
    ao('-e', '--engine', dest='engine', choices=sorted(engine_mapping.keys()),
       default='sqlite')
    ao('-d', '--database', dest='database', default=':memory:')

    options, models = parser.parse_args()
    print(render_models(
        models,
        engine=engine_mapping[options.engine],
        database=options.database,
        logging=options.logging))
