# -----------------------------------------------------------------------------
# Name:        GeneratePonyORM.py
# Purpose:     Utility for generating Pony ORM python file
#
# Author:      Will Smith <will.smith@noaa.gov>
#
# Created:     December, 2016
# License:     MIT
# ------------------------------------------------------------------------------
from pony.orm import Database
from peewee import FieldDescriptor, RelationDescriptor
from py.observer.ObserverDBModels import *
import py.observer.ObserverDBModels as oDB

db = Database()

def convert_peewee_orm_to_pony(output_filename='PonyDBModel.py'):
    header = '''# Generated by GeneratePonyORM.py

from pony.orm import Database, Required, Optional, Set, PrimaryKey

db = Database()


'''
    with open(output_filename, 'w') as f:

        f.write(header)

        things = dict([(name, cls) for name, cls in oDB.__dict__.items() if isinstance(cls, type)])
        for t in things:
            if 'py.observer.ObserverDBModels.' in str(things[t]):
                generated = generate_class_orm(things[t])
                print(generated)
                f.write(generated)


def generate_class_orm(obj):
    orm_text = 'class Pony{}(db.Entity):\n'.format(obj.__name__)
    orm_text += "    _table_ = '{}'\n".format(obj._meta.db_table)
    orm_text += generate_children(obj.__dict__.items())
    orm_text += '\n\n'
    return orm_text


def convert_to_pony_type(value):
    type_conversions = {
        # db_column=""
        str(FloatField): "Optional(float, column='{db_column}')",
        str(IntegerField): "Optional(int, column='{db_column}')",
        str(TextField): "Optional(str, column='{db_column}')",
        str(PrimaryKeyField): "PrimaryKey(int, column='{db_column}')",
        str(ForeignKeyField): "Required(int, column='{db_column}')",
        # str(ForeignKeyField): "Set('{rel_model}', reverse='{reverse}', column='{db_column}')",
    }

    type_str = str(type(value.field))
    if type_str in type_conversions.keys():
        # if 'ForeignKeyField' in type_str:
        #     rel_model = 'Pony' + str(value.rel_model.__name__).replace('py.observer.ObserverDBModels.', '')
        #     reverse = value.att_name
        #     return type_conversions[type_str].format(rel_model=rel_model,
        #                                              reverse=reverse,
        #                                              db_column=value.field.db_column)
        # else:
        return type_conversions[type_str].format(db_column=value.field.db_column)
    return type(value.field)


def generate_children(items):
    children_str = ''
    for attr, value in items:
        if type(value) == FieldDescriptor or type(value) == RelationDescriptor:
            children_str += '    {} = {}\n'.format(attr, convert_to_pony_type(value))

    return children_str


def generate_pony_db_orm():
    convert_peewee_orm_to_pony()

