# -*- coding: utf-8 -*-
#
# Modelo informix Municipalidad de Rosario
#

# librerias utlizadas
import os
import unicodedata
import pyodbc
import datetime

# for ide
if False:
    from db import myconf, log
    from sets import Set
    from ldapmr import ldapdict
    from util import dict_to_csv
    import csv

# configuracion entorno conector odbc
os.environ['INFORMIXDIR'] = '/var/informix'
os.environ['ODBCINI'] = '/etc/odbc.ini'
DRIVER = 'IBM INFORMIX ODBC DRIVER'
# diccionarios de entornos particulares
baseifx = {
    'seguusua': {
        'entorno': myconf.take('datos.seguusua_entorno'),
        'server': myconf.take('datos.seguusua_db'),
        'usuario': myconf.take('datos.seguusua_user'),
        'pass': myconf.take('datos.seguusua_pass')
    },
    'sysmaster': {
        'entorno': 'ifx_pri',
        'server': myconf.take('datos.seguusua_db'),
        'usuario': myconf.take('datos.seguusua_user'),
        'pass': myconf.take('datos.seguusua_pass')
    },
    'seguridadweb': {
        'entorno': myconf.take('datos.seguusua_entorno'),
        'server': myconf.take('datos.seguusua_db'),
        'usuario': myconf.take('datos.seguusua_user'),
        'pass': myconf.take('datos.seguusua_pass')
    },
    'siat': {
        'entorno': 'ifx_siat',
        'server': myconf.take('datos.seguusua_db'),
        'usuario': myconf.take('datos.seguusua_user'),
        'pass': myconf.take('datos.seguusua_pass')
    },
    'sua': {
        'entorno': 'ifx_sua',
        'server': myconf.take('datos.seguusua_db'),
        'usuario': myconf.take('datos.seguusua_user'),
        'pass': myconf.take('datos.seguusua_pass')
    }
}


def sanitize_seguusua(string):
    if string is None:
        return 'error'
    for key in ldapdict:
        string = string.replace(key, ldapdict[key])
    allowed_chars = Set('abcdefghijklmnopqrstuvwxyz' +
                        'ABCDEFGHIJKLMNOPQRSTUVWXYZ ')
    if Set(string).issubset(allowed_chars):
        return ['ok', string]
    else:
        log('caracter invalido ' + str(string))
        return ['error', string]


class Ifxmr:
    """clase para agrupar consultas"""
    def __init__(self, base):
        try:
            constr = 'DRIVER={%s};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (
                     DRIVER,
                     baseifx[base]['entorno'],
                     base,
                     baseifx[base]['usuario'],
                     baseifx[base]['pass'])
            con = pyodbc.connect(constr, autocommit=False)
            self.base = base
            self.cursor = con.cursor()
        except Exception as e:
            log(e)

    def query(self, sql):
        try:
            self.cursor.execute(sql)
            salida = normalizo_unicode(self.cursor.fetchall())
            return ['ok', salida]
        except Exception as e:
            log(e)
            return ['error', str(e)]

    def __del__(self):
        self.cursor.close()
        # log('conexion cerrada ' + str(self.base))


def normalizo_unicode(registro):
    fila = []
    for i in registro:
        columna = []
        for j in i:
            dato = ''
            if type(j) == unicode:
                dato = unicodedata.normalize('NFKD', j).encode(
                    'ascii', 'ignore').rstrip()
            elif type(j) == float:
                dato = str(int(j))
            elif j is None:
                dato = '-'
            elif str(type(j)) == "<class 'decimal.Decimal'>":
                dato = int(j)
            else:
                dato = j
            # log(dato)
            columna.append(dato)
        # log('resultado: '+str(columna))
        fila.append(columna)
    return fila


def ifx_sql(base, sql):
    """consulta-conexion simple"""
    log('base: ' + base + ' sql ' + sql)
    constr = 'DRIVER={%s};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (
        DRIVER,
        baseifx[base]['entorno'],
        base,
        baseifx[base]['usuario'],
        baseifx[base]['pass'])
    try:
        con = pyodbc.connect(constr, autocommit=False)
        cursor = con.cursor()
        cursor.execute(sql)
        registro = cursor.fetchall()
    except Exception as e:
        return ['error', e.args]
    # normalizo caracteres de registros unicode
    fila = normalizo_unicode(registro)
    cursor.close()
    con.close()
    return ['ok', fila]


def ifx_commit(base, sql):
    log('base: ' + base + ' sql ' + sql)
    constr = 'DRIVER={%s};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (
        DRIVER,
        baseifx[base]['entorno'],
        base,
        baseifx[base]['usuario'],
        baseifx[base]['pass'])
    try:
        con = pyodbc.connect(constr, autocommit=False)
        cursor = con.cursor()
        cursor.execute(sql)
        # verifico que el sql modifique registros antes de hacer commit
        modificados = cursor.rowcount
        if modificados == 0:
            return ['error', 'no se modifica ningun registro']
        else:
            mensaje = ['ok', str(modificados) + ' registro/s modificado/s']
            con.commit()
            cursor.close()
            con.close()
            return mensaje
        # registro=cursor.fetchall()
    except Exception as e:
        return ['error', e.args]


def seguusua(usuario_o_dni):
    """Funcion que recibe usuario o dni y retorna diccionario datos o estado
en seguusua. modelo usuario seguusua(omito algunos datos)
0 codusuario(login)        1 apeusuario(omitido)       2 nomusuario(omitido)
3 tpdusuario(tipo doc)     4 nrousuario(doc)           5 coddepend(omitido)
6 fecinicio                7 fecfin                    8 esttrabajo(omitido)
9 ippc(omito)             10 sistoper(omitido)        11 comentario
12 codcargo(omito)        13 id_dependencia(omitido)  14 id_cil(omitido)
15 trabajo_dias(omitido)  16 trabajo_desde(omitido)   17 trabajo_hasta(omitido)

salida  'USUARIO':$login
        'TIPO DOC':$tipo
        'DNI':$dni
        'FECHAING':$fecha_ingreso
        'FECFIN':$fecha_fin
        'COMENTARIO':$comentarios
"""
    q_seguusua = Ifxmr('seguusua')
    usuariodni = str(usuario_o_dni)
    if usuariodni.isdigit():
        dni = int(float(usuariodni))
        consulta = q_seguusua.query("""SELECT * FROM tusuario where nrousuario = '%s'""" % (dni))
    else:
        usuario = usuario_o_dni
        consulta = q_seguusua.query("""SELECT * FROM tusuario where codusuario = '%s'""" % (usuario))
    if consulta[0] == 'ok':
        # determino unicidad del registro
        if len(consulta[1]) == 0:
            salida = ['error', 'no existe usuario']
        elif len(consulta[1]) == 1:
            # consulto cil
            consultaidcil = q_seguusua.query("""SELECT id_cil FROM usuario where login = '%s'""" %(str(consulta[1][0][0])))
            if consultaidcil[0] == 'ok':
                if consultaidcil[1] == []:
                    cil = 'no registrado'
                else:
                    consultacil = q_seguusua.query("""SELECT nombre FROM cil where id_cil = '%s'""" %(str(consultaidcil[1][0][0])))
                    cil = str(consultacil[1][0][0])
            else:
                cil=str(consultaidcil[1])
            dict_consulta = {
                'USUARIO': str(consulta[1][0][0]),
                'APELLIDO': str(consulta[1][0][1]),
                'NOMBRE': str(consulta[1][0][2]),
                'TIPO DOC': str(consulta[1][0][3]),
                'DNI': str(consulta[1][0][4]),
                'FECING': str(consulta[1][0][6]),
                'FECFIN': str(consulta[1][0][7]),
                'COMENTARIO': str(consulta[1][0][11]),
                'CIL': cil,
                'CUIT': str(consulta[1][0][9]),
                'ACTUALIZACION': str(consulta[1][0][10])
                }
            # armo diccionario
            salida = ['ok', dict_consulta]
        else:
            salida = ['error', 'usuario dni duplicado']
    else:
        salida = ['error', str(consulta[1])]
    return salida


def seguusua_update(nombre, apellido, dni):
    updatenombre = ("""UPDATE tusuario SET nomusuario = '%s'
                    where nrousuario=%s""") % (nombre, dni)
    resultado1 = ifx_commit('seguusua', updatenombre)
    updatenombre = ("""UPDATE tusuario SET apeusuario = '%s'
                    where nrousuario=%s""") % (apellido, dni)
    resultado2 = ifx_commit('seguusua', updatenombre)
    if resultado1[0] == 'ok' and resultado2[0] == 'ok':
        return ['ok', str(resultado1[1]) + ' ' + str(resultado2[1])]
    else:
        return ['error', str(resultado1[1]) + ' ' + str(resultado2[1])]


def seguusua_set_cuit(usuario, cuit):
    updateippc = ("""UPDATE tusuario SET ippc = '%s'
                  where codusuario='%s'""") % (cuit, usuario)
    resultado1 = ifx_commit('seguusua', updateippc)
    if resultado1[0] == 'ok':
        return ['ok', str(resultado1[1])]
    else:
        return ['error', str(resultado1[1])]


def seguusua_set_comentario(usuario, comentario):
    if comentario == '':
        comentario = '-'
    updatecomentario = ("""UPDATE tusuario SET comentario = '%s'
                           where codusuario='%s'""") % (comentario, usuario)
    resultado1 = ifx_commit('seguusua', updatecomentario)
    if resultado1[0] == 'ok':
        return ['ok', str(resultado1[1])]
    else:
        return ['error', str(resultado1[1])]


# ejemplo update multiple
"""update tservusua set nroperfil="20",
codservidor="ncr" where codusuario = (select codusuario
from tusuario where codusuario ='hvianna0')"""


def seguusua_set_data(usuario, cuit, nombre, apellido, origen):
    actualiza = (datetime.datetime.today().isoformat()[0:19] +
                 '-' + str(origen)[:5])
    update = ("""UPDATE tusuario SET ippc='{cuit}',
        nomusuario='{nombre}', apeusuario='{apellido}',
        sistoper='{actualiza}' where codusuario='{usuario}'""").format(
        cuit=cuit,
        usuario=usuario,
        nombre=sanitize_seguusua(nombre)[1],
        apellido=sanitize_seguusua(apellido)[1],
        actualiza=actualiza)
    # return update
    resultado = ifx_commit('seguusua', update)
    return resultado


def ciles_todos():
    q_seguusua = Ifxmr('seguusua')
    consultacil = q_seguusua.query("""SELECT * FROM cil""")
    if consultacil[0] == 'ok':
        ciles = {}
        for i in consultacil[1]:
            ciles[i[0]] = {
                'id_cil': i[0],
                'nombre': i[1],
                'correo': i[2],
                'usuario': i[3],
                'fecha_hora': i[4]
            }
        respuesta = ['ok', ciles]
    else:
        respuesta = ['error', consultacil[1]]
    return respuesta


def lista_ciles_sti():
    consulta = ciles_todos()
    salida = []
    for i in consulta[1]:
        salida.append(consulta[1][i]['nombre'])
    return sorted(salida)


def tabla_tusuario_todos():
    usuarios = {}
    aux = ifx_sql('seguusua', """SELECT * FROM tusuario""")
    if aux[0] == 'ok':
        for i in aux[1]:
            registro = {
                'codusuario': i[0],
                'apeusuario': i[1],
                'nomusuario': i[2],
                'tpdusuario': i[3],
                'nrousuario': i[4],
                'coddepend': i[5],
                'fecinicio': i[6],
                'fecfin': i[7],
                'esttrabajo': i[8],
                'ippc': i[9],
                'sistoper': i[10],
                'comentario': i[11],
                'codcargo': i[12],
                'id_dependencia': i[13],
                'id_cil': i[14],
                'trabajo_dias': i[15],
                'trabajo_desde': i[16],
                'trabajo_hasta': i[17]
            }
            usuarios[str(registro['nrousuario'])] = registro
        return ['ok', usuarios]
    else:
        ['error', aux[1]]


def tabla_usuario_todos():
    usuarios = {}
    aux = ifx_sql('seguusua', """SELECT * FROM usuario""")
    if aux[0] == 'ok':
        for i in aux[1]:
            registro = {
                'id_usuario': i[0],
                'cod_doc': i[1],
                'nro_doc': i[2],
                'nombre': i[3],
                'apellido': i[4],
                'login': i[5],
                'id_dependencia': i[6],
                'superior': i[7],
                'id_cil': i[8],
                'trabajo_dias': i[9],
                'trabajo_desde': i[10],
                'trabajo_hasta': i[11],
                'id_oficina': i[12],
                'telefono': i[13],
                'notificacion_avance': i[14],
                'usuario': i[15],
                'fecha_hora': i[16]
            }
            usuarios[str(registro['nro_doc'])]=registro
        return ['ok',usuarios]
    else:
        ['error',aux[1]]


def seguusua_usuario_todos():
    usuarios = {}
    aux = ifx_sql('seguusua', """SELECT * FROM tusuario""")
    if aux[0] == 'ok':
        for i in aux[1]:
            registro = {
                'USUARIO': str(i[0]),
                'APELLIDO': str(i[1]),
                'NOMBRE': str(i[2]),
                'TIPO DOC': str(i[3]),
                'DNI': str(i[4]),
                'FECING': str(i[6]),
                'FECFIN': str(i[7]),
                'COMENTARIO': str(i[11])
            }
            usuarios[str(registro['USUARIO'])] = registro
        return ['ok', usuarios]
    else:
        ['error', aux[1]]


def seguusua_todos():
    ciles = ciles_todos()
    tabla_tusuario = tabla_tusuario_todos()
    tabla_usuario = tabla_usuario_todos()
    tusuarios = {}
    for dni in tabla_tusuario[1]:
        registro = tabla_tusuario[1][dni]
        if dni in tabla_usuario:
            registro['cil'] = ciles[1][tabla_usuario[1][dni]['id_cil']]['nombre']
        else:
            if tabla_tusuario[1][dni]['id_cil'] in ciles[1]:
                registro['cil'] = ciles[1][tabla_tusuario[1][dni]['id_cil']]['nombre']
            else:
                #log(str(dni)+' '+tabla_tusuario[1][dni]['id_cil'])
                registro['cil'] = tabla_tusuario[1][dni]['id_cil']
        tusuarios[dni]=registro
    return ['ok',tusuarios]

def seguusua_todos_usuario():
    ciles=ciles_todos()
    tabla_tusuario=tabla_tusuario_todos()
    tabla_usuario=tabla_usuario_todos()
    tusuarios={}
    for dni in tabla_tusuario[1]:
        registro=tabla_tusuario[1][dni]
        if dni in tabla_usuario:
            registro['cil']=ciles[1][tabla_usuario[1][dni]['id_cil']]['nombre']
        else:
            if tabla_tusuario[1][dni]['id_cil'] in ciles[1]:
                registro['cil']=ciles[1][tabla_tusuario[1][dni]['id_cil']]['nombre']
            else:
                #log(str(dni)+' '+tabla_tusuario[1][dni]['id_cil'])
                registro['cil']=tabla_tusuario[1][dni]['id_cil']
        tusuarios[tabla_tusuario[1][dni]['codusuario']]=registro
    return ['ok',tusuarios]


def sw_todos():
    """Funcion que recibe usuario y retorna estado en seguridadweb"""
    #return consulta
    #tabla datos_usr
    #sqlaux="""select * from datos_usr where datosusr_oid=%s"""%(usuariosw['datosusr_oid'])
    sqlaux="""select * from datos_usr"""
    consulta=ifx_sql('seguridadweb',sqlaux)
    datosusrsw={}
    if consulta[0]=='ok':
        for i in consulta[1]:
            datosusrsw[i[0]]={
            #'1]datosusr_oid':consulta[1][0][0],
            'nombres':i[1],
            'apellido':i[2],
            'direccion':i[3],
            'tipodoc':i[4],
            'nrodoc':i[5],
            'telefono':i[6],
            'email':i[7],
            'instituc_oid':i[8],
            'cargo':i[9]
            }
    else:
        return consulta
    
    sqlaux="""select * from datos_cta"""
    consulta=ifx_sql('seguridadweb',sqlaux)
    datosctasw={}
    if consulta[0]=='ok':
        for i in consulta[1]:
            datosctasw[i[0]]={
            'max_historico':i[1],
            'last_suc':i[2],
            'last_unsuc':i[3],
            'clogfal':i[4],
            'last_login_lock':i[5],
            'login_unlock_time':i[6],
            'fecinic':i[7],
            'fecfin':i[8],
            'feccrd':i[9],
            'dvautent':i[10],
            'minchautent':i[11],
            'maxdiasinact':i[12],
            'maxlogfal':i[13],
            'secclass_oid':i[14],
            'default_acl_oid':i[15],
            'tusr':i[16]
            }
    else:
        return consulta

    sqlaux="""select * from usuarios"""
    consulta=ifx_sql('seguridadweb',sqlaux)
    tablausuarios={}
    if consulta[0]=='ok':
        for i in consulta[1]:
            tablausuarios[i[4]]={
            'usuario_oid':i[0],
            'uid':i[1],
            'datosusr_oid':i[2],
            'datoscta_oid':i[3],
            'login':i[4],
            'autent_oid':i[5],
            'creador_oid':i[6]
            }
            try:
                datosusr={
                    'nombres':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['nombres'],
                    'apellido':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['apellido'],
                    'direccion':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['direccion'],
                    'tipodoc':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['tipodoc'],
                    'nrodoc':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['nrodoc'],
                    'telefono':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['telefono'],
                    'email':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['email'],
                    'instituc_oid':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['instituc_oid'],
                    'cargo':datosusrsw[tablausuarios[i[4]]['datosusr_oid']]['cargo'],
                    #
                    'max_historico':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['max_historico'],
                    'last_suc':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['last_suc'],
                    'last_unsuc':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['last_unsuc'],
                    'clogfal':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['clogfal'],
                    'last_login_lock':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['last_login_lock'],
                    'login_unlock_time':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['login_unlock_time'],
                    'fecinic':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['fecinic'],
                    'fecfin':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['fecfin'],
                    'feccrd':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['feccrd'],
                    'dvautent':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['dvautent'],
                    'minchautent':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['minchautent'],
                    'maxdiasinact':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['maxdiasinact'],
                    'maxlogfal':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['maxlogfal'],
                    'secclass_oid':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['secclass_oid'],
                    'default_acl_oid':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['default_acl_oid'],
                    'tusr':datosctasw[tablausuarios[i[4]]['datoscta_oid']]['tusr']
                    }
            except Exception as e:
                datosusr={
                    'nombres':'-',
                    'apellido':'-',
                    'direccion':'-',
                    'tipodoc':'-',
                    'nrodoc':'-',
                    'telefono':'-',
                    'email':'-',
                    'instituc_oid':'-',
                    'cargo':'-',
                    #
                    'max_historico':'-',
                    'last_suc':'-',
                    'last_unsuc':'-',
                    'clogfal':'-',
                    'last_login_lock':'-',
                    'login_unlock_time':'-',
                    'fecinic':'-',
                    'fecfin':'-',
                    'feccrd':'-',
                    'dvautent':'-',
                    'minchautent':'-',
                    'maxdiasinact':'-',
                    'maxlogfal':'-',
                    'secclass_oid':'-',
                    'default_acl_oid':'-',
                    'tusr':'-'
                    }
                log(e.args)
            tablausuarios[i[4]].update(datosusr)
        return ['ok',tablausuarios]
    else:
        return consulta



def sw_todos_grupos():
    """consulta masiva de grupos de todos los usuarios de seguridadweb"""
    #obtengo todos los datos de usuario
    usuarios = sw_todos()
    #obtengo todos los nombre de grupo
    consultanom = """SELECT grupo_oid,nomgrupo FROM grupos"""
    g_nombres=ifx_sql('seguridadweb',consultanom)[1]
    #proceso en forma de diccionario
    g_todos={}
    for i in g_nombres:
        g_todos[i[0]]=i[1]
    #obtengo pertenencia a grupos
    consulta_p="""SELECT miembro_oid,grupo_oid FROM miembros_grupos"""
    grupos_p=ifx_sql('seguridadweb',consulta_p)[1]
    p_todos={}
    for i in grupos_p:
        p_todos.setdefault(i[0], []).append(i[1])
    #
    #ensamblo info
    resultado={}
    for usuario in usuarios[1].keys():
        try:
            gid_usuario=p_todos[usuarios[1][usuario]['usuario_oid']]
            grupos=[]
            for i in gid_usuario:
                grupos.append(g_todos[i])
            resultado[usuario]=grupos
        except Exception as e:
            pass
    return resultado
#
# Operaciones sobre usuarios de seguusua
#


# reemplazar
def seguusua_datos(dni):
    campos = 'nrousuario,codusuario,apeusuario,nomusuario,tpdusuario,fecinicio,fecfin,comentario'
    consulta = """SELECT %s FROM tusuario where nrousuario = '%s'""" %(campos, dni)
    resultado = ifx_sql('seguusua', consulta)
    if resultado[0] == 'ok':
        # determino unicidad del registro
        if len(resultado[1]) == 0:
            salida = ['error', 'no existe usuario']
        elif len(resultado[1]) == 1:
            salida = ['ok', resultado[1][0]]
        else:
            salida = ['error', 'usuario dni duplicado']
    else:
        salida = resultado
    return salida


def agregar_seguusua(dni, apellido, nombre):
    # busco el dni si ya existe devuelvo que ya existe ese dni
    # if dni.isdigit
    log('intento agregar a seguusua:' + str(dni) + ' ' + str(apellido) +
        ' ' + str(nombre))
    if dni.isdigit():
        sql = """SELECT codusuario FROM tusuario where nrousuario = '%s'""" % (dni)
        consulta = ifx_sql('seguusua', sql)
    else:
        mensaje = ['error', 'dni invalido: ' + str(dni)]
        log(mensaje)
        return mensaje
    if (apellido == 'error') or (nombre == 'error'):
        return ['error', 'caracteres invalidos con dni: ' + str(dni)]
    if consulta[0] == 'ok':
        if consulta[1] == []:
            apellido_s = sanitize_seguusua(apellido)
            nombre_s = sanitize_seguusua(nombre)
            if apellido_s[0] == 'error' or [nombre_s][0] == 'error':
                return ['error', 'error: ' + str(apellido) + ' ' + str(nombre)]
            test_login = (nombre_s[1][0].lower() +
                          apellido_s[1].replace(' ', '')[0:6].lower())
            for numero in range(0, 10):
                loginpropuesto = test_login + str(numero)
                aux = ifx_sql('seguusua', """SELECT nrousuario FROM tusuario where codusuario = '%s'""" %(loginpropuesto))
                if aux[0] == 'ok':
                    if aux[1] == []:
                        creacion = (datetime.datetime.today().isoformat()[0:19] + '-nuevo')
                        sqlinsert = """INSERT INTO tusuario (codusuario, apeusuario, nomusuario, tpdusuario, nrousuario, coddepend, fecinicio, codcargo, sistoper) VALUES ('%s', '%s', '%s', 'DNI', %s, 1399, TODAY, 25, '%s')""" %(str(loginpropuesto),apellido_s[1].capitalize(),nombre_s[1].capitalize(),dni, creacion)
                        aux = ifx_commit('seguusua', sqlinsert)
                        if aux[0] == 'ok':
                            return ['ok', str(loginpropuesto)]
                        else:
                            return aux
            # si no inserto es que el login supera el digito 9
            test_login = nombre_s[1][0].lower() + apellido_s[1][0:5].lower()
            for numero in range(10, 100):
                loginpropuesto = test_login + str(numero)
                aux = ifx_sql('seguusua', """SELECT nrousuario FROM tusuario where codusuario = '%s'""" %(loginpropuesto))
                if aux[0] == 'ok':
                    if aux[1] == []:
                        sqlinsert = """INSERT INTO tusuario (codusuario, apeusuario, nomusuario, tpdusuario, nrousuario, coddepend, fecinicio, codcargo) VALUES ('%s', '%s', '%s', 'DNI', %s, 1399, TODAY, 25)""" %(str(loginpropuesto), apellido_s[1].capitalize(), nombre_s[1].capitalize(), dni)
                        aux = ifx_commit('seguusua', sqlinsert)
                        if aux[0] == 'ok':
                            return ['ok', str(loginpropuesto)]
                        else:
                            return aux
        else:
            mensaje = ['error',
                       'el usuario ya existe: ' + str(consulta[1][0][0])]
            log(mensaje)
            return mensaje
    else:
        log(consulta)
        return consulta


def seguusua_insert(login, nombre, apellido, dni, cuit, origen):
    actualiza = (datetime.datetime.today().isoformat()[0:19] +
                 '-' + str(origen)[:5])
    sqlinsert = ("""INSERT INTO tusuario (codusuario, apeusuario, nomusuario,
                 nrousuario, ippc, sistoper, tpdusuario) VALUES ('{login}',
                 '{apellido}', '{nombre}', '{dni}', '{cuit}',
                 '{actualiza}', 'DNI')""").format(login=login,
                                                  apellido=apellido,
                                                  nombre=nombre,
                                                  dni=dni,
                                                  cuit=cuit,
                                                  actualiza=actualiza
                                                  )
    aux = ifx_commit('seguusua', sqlinsert)
    return aux


def seguusua_fin(usuario):
    """setea fecha fin a usuario de seguusua"""
    updateffin="""UPDATE tusuario SET fecfin=TODAY WHERE codusuario='%s'"""%(usuario)
    resultado=ifx_commit('seguusua',updateffin)
    return resultado


def seguusua_rehablitar(usuario):
    """rehabilita a usuario en seguusua- saca fecha fin"""
    updateffin = """UPDATE tusuario SET fecfin='' WHERE codusuario='%s'"""%(usuario)
    resultado = ifx_commit('seguusua', updateffin)
    return resultado


def sw_grupos_usuario(usuario):
    """consulta grupos de seguridadweb"""
    # log('consulta '+str(usuario)+' en seguridadweb')
    # obtengo oid
    swusuario = sw_datos(usuario)
    if swusuario[0]=='ok':
        consulta="""SELECT grupo_oid FROM miembros_grupos WHERE miembro_oid = %s""" %(swusuario[1]['usuario_oid'])
        grupos_oid=ifx_sql('seguridadweb',consulta)
        if grupos_oid[0]=='ok':
            resultado=[]
            for i in grupos_oid[1]:
                #return i
                consultanom="""SELECT nomgrupo FROM grupos WHERE grupo_oid = %s""" %(i[0])
                nombre=ifx_sql('seguridadweb',consultanom)
                resultado.append(nombre[1][0][0])
            return ['ok',resultado]
        else:
            return grupos_oid
    else:
        # log('bb')
        return swusuario
    log('cc')
    return grupos_oid


def sw_grupos_dict():
    """consulto grupos de sw y devuelvo dict grupo:oidgrupo"""
    grupos = ifx_sql('seguridadweb', 'select grupo_oid,nomgrupo from grupos')
    dict_grupos = {}
    for registro in grupos[1]:
        dict_grupos[registro[1]] = registro[0]
    return dict_grupos


def sw_usuarios_grupo(grupo):
    """consulto todos los usuarios de un grupo"""
    try:
        todos_grupos = sw_todos_grupos()
        usuarios = []
        for usuario in todos_grupos.keys():
            if grupo in todos_grupos[usuario]:
                usuarios.append(usuario)
        return ['ok', usuarios]
    except Exception as e:
        return ['error', str(e)]


def activos_seguusua(lista):
    su_todos = seguusua_todos_usuario()
    activos = []
    for usuario in lista:
        try:
            if su_todos[1][usuario]['fecfin'] == '-':
                activos.append(usuario)
            elif su_todos[1][usuario]['fecfin'] < datetime.date.today():
                # tiene fecha fin valida no lo agrego
                pass
            else:
                log('error fecha ' + usuario)
        except Exception as e:
            log('error' + str(e) + ' con ' + str(usuario))
    return activos


def test_activos_seguusua():
    lista = sw_usuarios_grupo('usuarioaps')
    return activos_seguusua(lista[1])


def sw_baja_masiva(usuario):
    """baja masiva usuario en seguridadweb"""
    log('baja masiva '+str(usuario)+' en seguridadweb:')
    consultagrupos=sw_grupos_usuario(usuario)
    if consultagrupos[0]=='ok':
        grupos=consultagrupos[1]
    else:
        grupos='ninguno'
    #borro usuarios de grupos y pongo fecha fin
    borrasw="""DELETE FROM miembros_grupos WHERE miembro_oid = (SELECT uid FROM usuarios WHERE login ='%s')"""%(usuario)
    consultaffin="""SELECT * FROM datos_cta WHERE fecfin<TODAY AND fecfin>'2000-08-01 00:00:00' AND datoscta_oid = (SELECT datoscta_oid FROM usuarios WHERE login ='%s')"""%(usuario)
    updatesw="""UPDATE datos_cta SET clogfal=5,fecfin=TODAY WHERE datoscta_oid = (SELECT datoscta_oid FROM usuarios WHERE login ='%s')"""%(usuario)
    #falta validar que si el usuario tiene fecha fin no se debe realizar el update
    env.user = myconf.take('datos.seguusua_user')
    sw=FabricSupport()
    sw.dbaccess(myconf.take('datos.seguusua_db'),22,'seguridadweb',borrasw)
    resultado_borra=sw.result.split()
    log('ejecuta en sw: '+str(borrasw))
    log('borrados todos los grupos de seguridadweb a '+str(usuario)+' '+str(grupos))
    #compruebo que no tenga seteada fecha fin
    sw.dbaccess(myconf.take('datos.seguusua_db'),22,'seguridadweb',consultaffin)
    #
    #log('debug---: '+str(sw.result))
    if sw.result=='':
        sw.dbaccess(myconf.take('datos.seguusua_db'),22,'seguridadweb',updatesw)
        resultado_update=sw.result.split()
        log('ejecuta en sw: '+str(updatesw))
        log('seteado fecha fin en seguridadweb a '+str(usuario))
    else:
        resultado_update='fecha fin previa'
        log(str(usuario)+' '+str(resultado_update))
    mensaje=['baja ok','obs: '+str(resultado_borra)+' '+str(resultado_update)]
    log(mensaje)
    return mensaje


def sw_saco_fin(usuario):
    nofecfin = datetime.datetime(2100, 1, 1, 0, 0)
    updatesw = """UPDATE datos_cta SET fecfin='%s' WHERE datoscta_oid = (SELECT datoscta_oid FROM usuarios WHERE login ='%s')"""%(nofecfin,usuario)
    resultado = ifx_commit('seguridadweb', updatesw)
    return resultado


def sw_datos(usuario):
    """Funcion que recibe usuario y retorna estado en seguridadweb"""
    # tabla usuarios
    seguridadweb = Ifxmr('seguridadweb')
    sqlaux = """select * from usuarios where login='%s'""" % (usuario)
    consulta = seguridadweb.query(sqlaux)
    if consulta[0] == 'ok' and len(consulta[1]) == 1:
        usuariosw = {
            'usuario_oid': consulta[1][0][0],
            'uid': consulta[1][0][1],
            'datosusr_oid': consulta[1][0][2],
            'datoscta_oid': consulta[1][0][3],
            'login': consulta[1][0][4],
            'autent_oid': consulta[1][0][5],
            'creador_oid': consulta[1][0][6]
        }
    else:
        if type(consulta[1]) == tuple:
            return consulta
        else:
            return ['error', 'no existe en seguridad web']

    # tabla datos_usr
    sqlaux = """select * from datos_usr where datosusr_oid=%s""" % (usuariosw['datosusr_oid'])
    consulta = seguridadweb.query(sqlaux)
    if consulta[0] == 'ok' and len(consulta[1]) == 1:
        datosusrsw = {
            # 'datosusr_oid':consulta[1][0][0],
            'nombres': consulta[1][0][1],
            'apellido': consulta[1][0][2],
            'direccion': consulta[1][0][3],
            'tipodoc': consulta[1][0][4],
            'nrodoc': consulta[1][0][5],
            'telefono': consulta[1][0][6],
            'email': consulta[1][0][7],
            'instituc_oid': consulta[1][0][8],
            'cargo': consulta[1][0][9]
        }
        usuariosw.update(datosusrsw)
    else:
        return ['error', 'algo esta mal con datos_usr de sw']

    # tabla datos_cta
    sqlaux = """select * from datos_cta where datoscta_oid=%s""" % (usuariosw['datoscta_oid'])
    consulta = seguridadweb.query(sqlaux)
    if consulta[0] == 'ok' and len(consulta[1]) == 1:
        datosctasw = {
            # 'datoscta_oid':consulta[1][0][0],
            'max_historico': consulta[1][0][1],
            'last_suc': consulta[1][0][2],
            'last_unsuc': consulta[1][0][3],
            'clogfal': consulta[1][0][4],
            'last_login_lock': consulta[1][0][5],
            'login_unlock_time': consulta[1][0][6],
            'fecinic': consulta[1][0][7],
            'fecfin': consulta[1][0][8],
            'feccrd': consulta[1][0][9],
            'dvautent': consulta[1][0][10],
            'minchautent': consulta[1][0][11],
            'maxdiasinact': consulta[1][0][12],
            'maxlogfal': consulta[1][0][13],
            'secclass_oid': consulta[1][0][14],
            'default_acl_oid': consulta[1][0][15],
            'tusr': consulta[1][0][16]
        }
        usuariosw.update(datosctasw)
    else:
        return ['error', 'algo esta mal con datos_cta de sw']

    # tabla autent
    sqlaux = """select * from autent where autent_oid=%s""" % (usuariosw['autent_oid'])
    consulta = seguridadweb.query(sqlaux)
    if consulta[0] == 'ok' and len(consulta[1]) == 1:
        datosautentsw = {
            # 'autent_oid':consulta[1][0][0],
            'tipo_autent': consulta[1][0][1],
            'token_string': consulta[1][0][2],
            'token_real': consulta[1][0][3],
            'mautent': consulta[1][0][4]
        }
        usuariosw.update(datosautentsw)
    else:
        return ['error', 'algo esta mal con datos_cta de sw']

    # grupos
    grupos = []
    consulta = """SELECT grupo_oid FROM miembros_grupos WHERE miembro_oid = %s""" % (usuariosw['usuario_oid'])
    grupos_oid = seguridadweb.query(consulta)
    if grupos_oid[0] == 'ok':
            for i in grupos_oid[1]:
                consultanom = """SELECT nomgrupo FROM grupos WHERE grupo_oid = %s""" % (i[0])
                nombre = seguridadweb.query(consultanom)
                grupos.append(nombre[1][0][0])
    usuariosw.update({'grupos': grupos})
    return ['ok', usuariosw]


def sw_cambio_pass(usuario, clave):
    datasw = sw_datos(usuario)
    if datasw[0] == 'ok':
        #validaciones y sql heredados de perl-script
        if datasw[1]['usuario_oid']==0 or datasw[1]['datoscta_oid']==0:
            return ['error','Error interno al determinar oids']
        else:
            sqlqoid="""select max(autent.autent_oid)+1 as autent_oid from autent"""
            qoid=ifx_sql('seguridadweb',sqlqoid)
            if qoid[0]=='ok':
                salt='AA'
                hashpwd=crypt.crypt(clave,salt)
                last_login_time=datetime.datetime(1970, 1, 1, 0, 0)
                time_now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                try:
                    aux0=ifx_commit('seguridadweb',"""insert into autent (autent_oid,tipo_autent,token_string,token_real,mautent) values ('%s',0,'%s',null, 0)"""%(qoid[1][0][0],hashpwd))
                    aux1=ifx_sql('seguridadweb',"""select * from autent_hist where usuario_oid=%s order by fecha_cambio desc"""%(datasw[1]['usuario_oid']))
                    if aux1[1]==[]:
                        aux2=ifx_commit('seguridadweb',"""insert into autent_hist (usuario_oid, fecha_cambio, autentant_oid) values (%s, TODAY, 1)"""%(datasw[1]['usuario_oid']))
                    else:
                        aux2=ifx_commit('seguridadweb',"""update autent_hist set fecha_cambio=TODAY where usuario_oid=%s"""%(datasw[1]['usuario_oid']))
                    aux3=ifx_commit('seguridadweb',"""update usuarios set autent_oid=%s where usuario_oid=%s"""%(qoid[1][0][0],datasw[1]['usuario_oid']))
                    aux4=ifx_commit('seguridadweb',"""update datos_cta set clogfal=0, last_login_lock='%s', feccrd='%s' where datoscta_oid=%s"""%(str(last_login_time),time_now,datasw[1]['datoscta_oid']))
                    if aux1[0]=='error' or aux2[0]=='error' or aux3[0]=='error' or aux4[0]=='error':
                        log(' aux1'+str(aux1)+' aux2'+str(aux2)+' aux3'+str(aux3)+' aux4'+str(aux4))
                except Exception as e:
                    return ['error',e.args]
                return['ok', 'clave cambiada en sw']
            else:
                return qoid
    else:
        return datasw


def sw_desbloquear(usuario):
    """
    desbloquea usuario
    """
    datasw = sw_datos(usuario)
    if datasw[0] == 'ok':
        rtdo = ifx_commit(
            'seguridadweb',
            """update datos_cta set clogfal=0, last_login_lock='1970-01-01 05:00:00' where datoscta_oid=%s"""%(datasw[1]['datoscta_oid']))
        if rtdo[0] == 'ok':
            return ['ok', 'desbloqueado ' + str(usuario) + ' en sw']
        else:
            return rtdo
    else:
        return datasw


#
# consultas informix masivas
#

def consulta_permisos_ifx(usuario):
    env.user = myconf.take('datos.seguusua_user')
    ifxsrv=FabricSupport()
    comando="""/usr/local/seguridad/bin/useradm_priv_ifx -u %s"""%(usuario)
    ifxsrv.run(myconf.take('datos.seguusua_db'),22,comando)
    resultado=ifxsrv.result.replace('\t',' ').split('\r\n')
    log('consulta ifx: '+str(usuario)+' resultado: '+str(resultado))
    return resultado

def revoca_permisos_ifx(usuario):
    log('inicio revoca permisos ifx '+str(usuario))
    env.user = myconf.take('datos.usradmin_user')
    ifxsrv=FabricSupport()
    comando="""sudo -u informix /usr/local/seguridad/bin/useradm_revokeInfPrivs.10 -u %s"""%(usuario)
    ifxsrv.run(myconf.take('datos.usradmin_db'),22,comando)
    aux=ifxsrv.result.replace('\t',' ').split('\r\n')
    resultado=sorted(list(set(aux)))
    log('revoca permisos ifx: '+str(resultado))
    if resultado[0].startswith('El usuario'):
        mensaje={'estado':'ok','mensaje':resultado}
    else:
        mensaje={'estado':'ok','mensaje':'permisos revocados'}
    return mensaje


def copia_permisos_ifx(usuario, referencia):
    env.user = myconf.take('datos.seguusua_user')
    ifxsrv = FabricSupport()
    comando = """sudo -u informix /usr/local/seguridad/bin/useradm_grantInfPrivs.10 -u %s -g %s"""%(referencia,usuario)
    ifxsrv.run(myconf.take('datos.seguusua_db'),22,comando)
    aux = ifxsrv.result.replace('\t', ' ').split('\r\n')
    resultado = sorted(list(set(aux)))
    mensaje = {'estado': 'ok', 'mensaje': 'permisos copiados'}
    log(resultado)
    return mensaje


# def seguusua_to_csv():
#    """."""
#    a = ifx_sql('seguusua', 'select * from tusuario')
#    with open(dir_files + 't-usuarios.seguusua.csv','wb') as f:
#        writer = csv.writer(f)
#        writer.writerows(a[1])


def seguusua_to_csv():
    todos = seguusua_todos()
    return dict_to_csv(todos[1], 'seguusua_todos')[1]


# sobre serviciosti

def sti_consulta_ultimo_todos():
    aux = ifx_sql('seguusua', "select a.id_usuario, max (a.fecha_hora) as fec_ult_ti, nro_doc from acceso a, usuario b where a.id_usuario=b.id_usuario group by a.id_usuario, nro_doc order by a.id_usuario, nro_doc")
    salida = {}
    if aux[0] == 'ok':
        for i in aux[1]:
            salida[i[2]] = i[1]
    return salida


def sw_grupos_all():
    """devuelvo lista de [oid,grupo] de sw"""
    aux = ifx_sql('seguridadweb', 'select grupo_oid,nomgrupo from grupos')
    return aux


def sw_agregar_grupo(usuario, grupo):
    # obtengo grupos
    swgrupos = sw_grupos_all()
    if swgrupos[0] == 'ok':
        for i in swgrupos[1]:
            if i[1] == grupo:
                grupo_oid = i[0]
        if not 'grupo_oid' in locals():
            # aunque no deberia entrar nunca aqui si valide el grupo
            return ['error', 'no existe el grupo']
        # compruebo que el usuario exista
        swdatos=sw_datos(usuario)
        if swdatos[0]=='ok':
            sqlinsert="""insert into miembros_grupos(grupo_oid, miembro_oid, tipo_miembro) values (%s, %s, 1)"""%(grupo_oid,swdatos[1]['usuario_oid'])
            resultado=ifx_commit('seguridadweb',sqlinsert)
            return resultado
        else:
            return swdatos
    else:
        return swgrupos

def sw_eliminar_grupo(usuario,grupo):
    # comprobar que exista grupo
    swgrupos = sw_grupos_all()
    if swgrupos[0]=='ok':
        for i in swgrupos[1]:
            if i[1]==grupo:
                grupo_oid=i[0]
        if not 'grupo_oid' in locals():
            #aunque no deberia entrar nunca aqui si valide el grupo
            return ['error','no existe el grupo']
        #compruebo que el usuario exista
        swdatos=sw_datos(usuario)
        if swdatos[0]=='ok':
            #sqlinsert="""insert into miembros_grupos(%s, %s, 1)"""%(grupo_oid,swdatos[1]['usuario_oid'])
            sqldelete="""delete from miembros_grupos where (grupo_oid=%s and miembro_oid=%s)"""%(grupo_oid,swdatos[1]['usuario_oid'])
            resultado=ifx_commit('seguridadweb',sqldelete)
            return resultado
        else:
            return swdatos
    else:
        return swgrupos


#funciones especiales
def cruzo_sw_seguusua():
    #reviso que los usuarios creados en seguridadweb existan en seguusua
    todosseguusua=seguusua_todos()[1]
    todossw=sw_todos()
    log('inicio cruce: '+str(len(todosseguusua))+'reg seguusua con '+str(len(todossw[1]))+' registros sw')
    faltanenseguusua=[]
    for i in todossw[1]:
        faltanenseguusua.append(i)
        for k in todosseguusua[j]:
            if k['USUARIO']==i:
                try:
                    faltanenseguusua.remove(i)
                except Exception as e:
                    pass
        #log(str(todossw[1][i]['fecfin']))
        if todossw[1][i]['fecfin']!=datetime.datetime(2100, 1, 1, 0, 0):
            try:
                faltanenseguusua.remove(i)
            except Exception as e:
                pass


    log('fin cruce')
    nombre_archivo='cruce_sw_seguusua_'+str(id_generator(20))+'.csv'
    with open(nombre_archivo, 'wb') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        for i in faltanenseguusua:
            wr.writerow([i])
        #wr.writerow(faltanenseguusua)
    log('escrito '+str(nombre_archivo))
    return faltanenseguusua


def interseccion_grupos_seguusua(codservidor,menu,lista_opcion):
    resultado=[]
    for i in lista_opcion:
        aux=ifx_sql('seguusua',"""SELECT nroperfil from topcionperfil where (codservidor='%s' and nromenu=%s and nroopcion=%s)"""%(codservidor,menu,i))[1]
        lista_opcion=[]
        for i in aux:
            lista_opcion.append(i[0])
        resultado.append(set(lista_opcion))
    return set.intersection(*resultado)
