# -*- coding: utf8 -*-
import os
import sys
import transaction
import time
import lxml.etree as ET

from sqlalchemy import engine_from_config
from sqlalchemy import create_engine, MetaData, Table
import unicodedata
import urllib
# Usefull tools
from slugify import slugify
from sqlite3 import dbapi2 as sqlite
import sqlite3
from os import path
from pyramid.paster import (
    get_appsettings,
    setup_logging,
    )
from string import printable
from random import choice
from sqlalchemy import orm, or_

from jm2l.models import *
from datetime import datetime

def usage(argv):
    cmd = os.path.basename(argv[0])
    print('usage: %s <config_uri>\n'
          '(example: "%s development.ini")' % (cmd, cmd)) 
    sys.exit(1)

def make_session(connection_string):
    engine = create_engine(connection_string, echo=False, convert_unicode=True)
    Session = sessionmaker(bind=engine)
    return Session(), engine

def quick_mapper(table):
    Base = declarative_base()
    class GenericMapper(Base):
        __table__ = table
    return GenericMapper

def pull_data(from_db, to_db, tables):
    source, sengine = make_session(from_db)
    smeta = MetaData(bind=sengine)
    destination, dengine = make_session(to_db)

    for table_name in tables:
        print('Processing', table_name)
        print('Pulling schema from source server')
        table = Table(table_name, smeta, autoload=True)
        print('Creating table on destination server')
        table.metadata.create_all(dengine)
        NewRecord = quick_mapper(table)
        columns = table.columns.keys()
        print('Transferring records')
        for record in source.query(table).all():
            data = dict(
                [(str(column), getattr(record, column)) for column in columns]
            )
            if table_name=='salle':
                if data['place_type']=='Ateliers':
                    data['place_type']='Atelier'
            if table_name=='events':
                if data['event_type']=='Concert':
                    data['event_type']='MAO'                    
            try:
                destination.merge(NewRecord(**data))
            except:
                print(data)
                pass
    print('Committing changes')
    destination.commit()


def main(argv=sys.argv):
    connection_string = "sqlite:////home/tr4ck3ur/git_repository/jm2l/JM2L.sqlite"
    engine = create_engine(connection_string, echo=False, convert_unicode=True)
    DBSession.configure(bind=engine)
    Users = DBSession.query(User)
    ListUser = filter(lambda x: x.is_Intervenant, Users)
    for i in ListUser:
        print(i.mail)

def main4(argv=sys.argv):
    import csv
    from sqlalchemy import func

    connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"

    if 1:
        conn = sqlite3.connect("/home/tr4ck3ur/Dev/jm2l/JM2L.sqlite")
        c = conn.cursor()
        try:
            c.execute("ALTER TABLE users ADD COLUMN wifi_user VARCHAR(80);")
            c.execute("ALTER TABLE users ADD COLUMN wifi_pass VARCHAR(80);")        
        except:
            pass # handle the error
        c.close()

    engine = create_engine(connection_string, echo=False, convert_unicode=True)
    DBSession.configure(bind=engine)    

    with transaction.manager:    
        f = open("/home/tr4ck3ur/Dev/jm2l/wifi-11-11-pass.csv", 'rt')
        try:
            reader = csv.reader(f)
            for row in reader:
                prenom, nom, w_user, w_pass = row
                slug = unicode( slugify(prenom +" "+nom) )
                u = DBSession.query(User)\
                    .filter(User.slug==slug).first()
                if u:
                    u.wifi_user = w_user
                    u.wifi_pass = w_pass
                    DBSession.merge(u)
                print(row, u)
        finally:
            f.close()
        
    if 0:

        p0, p1  = orm.aliased(User,name="p0"), orm.aliased(User ,name="p1")
        import pprint


def main_3(argv=sys.argv):
    connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"
    engine = create_engine(connection_string, echo=True, convert_unicode=True)
    DBSession.configure(bind=engine)
    p0, p1  = orm.aliased(User, name="p0"), orm.aliased(User , name="p1")
    import pprint
    
    ## permtation
    with transaction.manager:    
        Datas = DBSession.query(p0, p1)\
                .filter(p0.slug==p1.slug)\
                .filter(p0.uid!=p1.uid)\
                .filter(p0.last_logged<p1.last_logged)\
                .with_entities(p0.slug,p0.uid,p1.uid).all()
        for slug, idsrc, iddst in Datas:
            print(slug)
            # Events
            Events = DBSession.query(User_Event)\
                    .filter(User_Event.user_uid==idsrc)
            for uev in Events:
                uev.user_uid = iddst
                DBSession.merge(uev)
            DBSession.flush()
            
            UTiers = DBSession.query(User_Tiers)\
                    .filter(User_Tiers.user_uid==idsrc)
            for ut in UTiers:
                ut.user_uid=iddst
                DBSession.merge(ut)
            DBSession.flush()
            
            orig = DBSession.query(User).filter(User.uid==idsrc).one()
            DBSession.delete(orig)
            #User_Event.year_uid, Event.name
            #pprint.pprint(  )
            #pprint.pprint( DBSession.query( user_id

def main_(argv=sys.argv):
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    DBSession.flush()
    pull_data("sqlite:////home/tr4ck3ur/Dev/jm2l/PRD_JM2L.sqlite",
              "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite",
              ['users',
               'staff_tasks_area',
               'staff_tasks',
               'user_event_link',
               'jm2l_year',
               'users',
               'tiers_opt',
               'tiers',
               'role_tiers_link',
               'user_tiers_link',
               'medias',
               'phy_salle',
               'salle',
               'place',
               'itineraire',
               'exchange_category',
               'exchanges',
               'sejour',
               'events',
               'entries'
               ])
              



def Initialize():
    with transaction.manager:
        admin = User(nom=u'jm2l', prenom=u'contact',
            slug=u'contact jm2l', password=u'jm2l',
            mail=u'contact@jm2l.linux-azur.org',
            Staff=1
            )
        DBSession.add(admin)

        # Create 2015 year event
        jm2l = JM2L_Year(year_uid=2015, 
                state="Ongoing",
                description=u"%d, %dème édition des JM2L." % ( 2015, 9 ),
                start_time=datetime.strptime("28-11-2015 10:00","%d-%m-%Y %H:%M"),
                end_time=datetime.strptime("28-11-2015 19:00","%d-%m-%Y %H:%M")
                )
        DBSession.add(jm2l)

        # Create 2015 Physic room event
        phy_salle = SallePhy( name=u"Polytech salle 211",
            description=u"Salle informatique, présence de postes de travail",)
        DBSession.add(phy_salle)
        DBSession.flush()

        # Create matching room place (Name could change each year)
        salle = Salles(name=u"Mystère",  description=u"Salle Mystère",
                    phy_salle_id = phy_salle.uid,
                    year_uid = jm2l.year_uid)
        DBSession.add(salle)

    with transaction.manager:
        # Re-Generate passwords
        for u in DBSession.query(User).filter(User.Staff==None):
            # Fix empty fields
            password = ''.join(choice(printable[:-6]) for _ in range(12))
            u.password = password
            u.Staff = 0
            DBSession.merge(u)
            print(u.nom, u.prenom, u.Staff)
