#!/usr/bin/python
 
from datetime import date,datetime
import sqlalchemy
import json
import pprint 
import uuid
import logging
import os

import utils
from config import ComicStreamerConfig
from folders import AppFolders

from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import deferred
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, Float, String, DateTime, BigInteger, Text, LargeBinary, Table, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy import create_engine, func
from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.associationproxy import _AssociationList
from sqlalchemy.orm.properties import \
                        ColumnProperty,\
                        CompositeProperty,\
                        RelationshipProperty
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
from sqlalchemy.types import String
from sqlalchemy.dialects import mysql

mysql_active = ComicStreamerConfig()['database']['engine'].lower() == "mysql"

SCHEMA_VERSION=6

Base = declarative_base()
Session = sessionmaker()

def resultSetToJson(rset, listname="aaData", total=None):
    return json.dumps(resultSetToDict(rset, listname, total), cls=alchemy_encoder(), check_circular=False)

def resultSetToDict(rset, listname="aaData", total=None):
    l = []
    for r in rset:
        l.append(r)
        
    results_dict = {}
    results_dict[listname] = l
    results_dict['page_count'] = len(l)
    if total is None:
        results_dict['total_count'] = len(l)
    else:
        results_dict['total_count'] = total
      
    return results_dict


def alchemy_encoder():
    _visited_objs = []
    class AlchemyEncoder(json.JSONEncoder):
        def default(self, obj):

            if isinstance(obj,_AssociationList):
                # Convert association list into python list
                return list(obj)
            
            if isinstance(obj.__class__, DeclarativeMeta):
                # don't re-visit self
                if obj in _visited_objs:
                    return None
                _visited_objs.append(obj)

                # an SQLAlchemy class
                fields = {}
                for field in [x for x in dir(obj) if not x.startswith('_')
                                                    and x != 'metadata'
                                                    and not x.endswith('_raw')
                                                    and x != "persons" 
                                                    and x != "roles" 
                                                    and x != "issue_num" 
                                                    and x != "file" 
                                                    and x != "folder"
                                                    and x != "thumbnail"
                                                    ]:
                    value = obj.__getattribute__(field)
                    if (isinstance(value, date)): 
                        value = str(value)
                    
                    if value is not None:
                        fields[field] = value
                    else:
                        fields[field] = ""
                        
                # a json-encodable dict
                return fields

            return json.JSONEncoder.default(self, obj)
    return AlchemyEncoder


        
        
# Junction table
comics_characters_table = Table('comics_characters', Base.metadata,
    Column('comic_id', Integer, ForeignKey('comics.id')),
    Column('character_id', Integer, ForeignKey('characters.id'))
)

# Junction table
comics_teams_table = Table('comics_teams', Base.metadata,
    Column('comic_id', Integer, ForeignKey('comics.id')),
    Column('team_id', Integer, ForeignKey('teams.id'))
)

# Junction table
comics_locations_table = Table('comics_locations', Base.metadata,
    Column('comic_id', Integer, ForeignKey('comics.id')),
    Column('location_id', Integer, ForeignKey('locations.id'))
)

# Junction table
comics_storyarcs_table = Table('comics_storyarcs', Base.metadata,
    Column('comic_id', Integer, ForeignKey('comics.id')),
    Column('storyarc_id', Integer, ForeignKey('storyarcs.id'))
)

# Junction table
comics_alternateseries_table = Table('comics_alternateseries', Base.metadata,
    Column('comic_id', Integer, ForeignKey('comics.id')),
    Column('alternateseries_id', Integer, ForeignKey('alternateseries.id'))
)
# Junction table
comics_generictags_table = Table('comics_generictags', Base.metadata,
     Column('comic_id', Integer, ForeignKey('comics.id')),
     Column('generictags_id', Integer, ForeignKey('generictags.id'))
)

# Junction table
comics_genres_table = Table('comics_genres', Base.metadata,
     Column('comic_id', Integer, ForeignKey('comics.id')),
     Column('genre_id', Integer, ForeignKey('genres.id'))
)

# Junction table
comics_blacklist_table = Table('comics_blacklist', Base.metadata,
    Column('comic_id', Integer, ForeignKey('comics.id')),
    Column('blacklist_id', Integer, ForeignKey('blacklist.id')),
    Column('page', Integer, primary_key=True),
    Column('ts',DateTime, default=datetime.utcnow)
)
"""
# Junction table
readinglists_comics_table = Table('readinglists_comics', Base.metadata,
     Column('comic_id', Integer, ForeignKey('comics.id')),
     Column('readinglist_id', Integer, ForeignKey('readinglists.id'))
)
"""

class CreditComparator(RelationshipProperty.Comparator):
    def __eq__(self, other):
        return self.person() == other