# coding: utf-8
from flask import render_template, flash, redirect, url_for, request, Blueprint, session as httpsession, g, current_app
from flask_login import login_user, current_user, logout_user, login_required
from user_agents import parse
from webinterface import db, bcrypt
from webinterface.models.system import Ipaddr, Dispositivo, Sesion, Identidad, Ruta, Registro, Conexion, Correo, Sitio, Persona
from webinterface.models.documentos import Documento
from webinterface.models.gestion import Comision, Miembro, Objetivo
from .utils import es_local
import datetime
import markdown2

## Core provee la funcionalidad basica de autentificación usando las credenciales de iLab

main = Blueprint('main', __name__)

@main.route("/")
@main.route("/home")
def home():
    if current_user.is_authenticated:
        return redirect(url_for('main.dashboard'))
    else:
        return redirect(url_for('main.login'))

@main.route("/dashboard")
@login_required
def dashboard():
    msg = '''Bienvenidos, este sitio es un sistema de información automatizado del transporte público en el Gran Concepción.

En el menú lateral, se muestran los diferentes módulos a los que tiene acceso y en caso de presentarse algun problema, favor indicarlo a soporte@ilab.cl. La plataforma está en desarrollo por lo que es posible que presente intermitencias hata su lanzamiento.
'''
    return render_template('dashboard.html', title='Sistema de Gestión del Transporte Público', msg=markdown2.markdown(msg))

@main.route("/about")
def about():
    return render_template('about.html', title='About')

@main.route("/login", methods=['GET', 'POST'])
def login():
    return redirect('https://tpmc.ilab.cl/system/login')

@main.route("/logout")
def logout():
    return redirect('https://tpmc.ilab.cl/system/logout')

@main.before_app_first_request
def init_database():
    try:
#        db.drop_all()
        db.create_all()

        id_internet = Identidad.query.filter(Identidad.login=='Internet').one_or_none()
        if id_internet is None:
            id_internet = Identidad(login='Internet')
            db.session.add(id_internet)

        id_intranet = Identidad.query.filter(Identidad.login=='Intranet').one_or_none()
        if id_intranet is None:
            id_intranet = Identidad(login='Intranet')
            db.session.add(id_intranet)

        id_buscador = Identidad.query.filter(Identidad.login=='Buscador').one_or_none()
        if id_buscador is None:
            id_buscador = Identidad(login='Buscador')
            db.session.add(id_buscador)

        clave_persona = bcrypt.generate_password_hash('hola1234').decode('utf-8')
        ifiguero_persona = Persona.query.filter(login=='ifiguero').one_or_none()
        if ifiguero_persona is None:
            ifiguero_persona = Persona(login='ifiguero', clave=clave_persona, rut='13955977-0', nombres='Israel', apellidop='Figueroa')
            db.session.add(ifiguero_persona)
        else:
            ifiguero_persona.clave=clave_persona

        clave_tpmc = bcrypt.generate_password_hash('tpmc').decode('utf-8')
        tpmc_persona = Persona.query.filter(login=='tpmc').one_or_none()
        if tpmc_persona is None:
            tpmc_persona = Persona(login='tpmc', clave=clave_tpmc, rut='tpmc', nombres='Transporte', apellidop='Público')
            db.session.add(tpmc_persona)
        else:
            tpmc_persona.clave=clave_tpmc

        db.session.commit()

        uuid_nill = "00000000000000000000000000000000"
        root_doc = Documento.query.filter(Documento.hash==uuid_nill).one_or_none()
        if root_doc is None:
            root_doc = Documento(hash=uuid_nill, nombre='Root', autorid=ifiguero_persona.id)
            db.session.add(root_doc)

        root_comision = Comision.query.filter(id==1).one_or_none()
        if root_comision is None:
            root_comision = Comision(id=1, creado=1, nombre='root')
            db.session.add(root_comision)

        db.session.commit()

        ifiguero_comision = Miembro.query.filter(Miembro.personaid==ifiguero_persona.id, Miembro.comisionid==1).one_or_none()
        if ifiguero_comision is None:
            ifiguero_comision = Miembro(personaid=ifiguero_persona.id, comisionid=1)
            db.session.add(ifiguero_comision)

        root_object = Objetivo.query.filter(Objetivo.id==1).one_or_none()
        if root_object is None:
            root_object = Objetivo(id=1, parentid=1, responsableid=1, tipo='root', nombre='root')
            db.session.add(root_object)


        db.session.commit()

    except:
        import traceback
        current_app.logger.debug(traceback.format_exc())


@main.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(current_app.root_path, 'static'), 'favicon.ico', mimetype='image/vnd.microsoft.icon')


@main.before_app_request
def registra_sesion():

    if request.headers.getlist("X-Forwarded-For"):
        remote_ip = request.headers.getlist("X-Forwarded-For")[0]
    else:
        remote_ip = request.environ['REMOTE_ADDR']
    uadata = parse(request.user_agent.string)

    ip = Ipaddr.query.filter_by(ipaddr=remote_ip).one_or_none()
    if ip is None:
        ip = Ipaddr(ipaddr=remote_ip)
        db.session.add(ip)
        db.session.commit()

    if 'sid' in httpsession:
        sesion = Sesion.query.filter_by(id=httpsession['sid']).one_or_none()
        if sesion is None:
            httpsession.pop('sid', None)
        else:
            dispositivo = Dispositivo.query.filter_by(id=sesion.dispositivoid, parsed_ua=str(uadata)).one_or_none()
            if dispositivo is None:
                httpsession.pop('sid', None)
            else:
                conexion = Conexion.query.filter_by(ipaddrid=ip.id, sesionid=sesion.id).one_or_none()
                Ident = sesion.identidad
                if conexion is None:
                    conexion = Conexion(ipaddr=ip, sesion=sesion)
                    db.session.add(conexion)
                    db.session.commit()

    if 'sid' not in httpsession:

        dispositivo = Dispositivo.query.filter_by(useragent=request.user_agent.string).one_or_none()
        if dispositivo is None:
            dev = uadata.is_pc and "PC" or uadata.device.family
            os = ("%s %s" % (uadata.os.family, uadata.os.version_string)).strip()
            browser = ("%s %s" % (uadata.browser.family, uadata.browser.version_string)).strip()

            dispositivo = Dispositivo(useragent=request.user_agent.string, dev=dev , os=os , browser=browser, parsed_ua=str(uadata))
            db.session.add(dispositivo)
            db.session.commit()

        if uadata.is_bot:
            Ident = Identidad.query.filter_by(login='Buscador').one()
        elif es_local(remote_ip):
            Ident = Identidad.query.filter_by(login='Intranet').one()
        else:
            Ident = Identidad.query.filter_by(login='Internet').one()

        sesion = Sesion(identidad=Ident, dispositivo=dispositivo)
        db.session.add(sesion)
        db.session.commit()

        conexion = Conexion(ipaddr=ip, sesion=sesion)
        db.session.add(conexion)
        db.session.commit()


# agregamos el registro asociado a la solicitud actual
# a la sesion que esta actualmente cargada. Dejamos la sesion guardada en
# la variable global g.

    if '/reset_password' in str(request.path):
        rpth = '/reset_password'
    else:
        rpth = str(request.path)

    solicitud = Ruta.query.filter_by(ruta=rpth).first()
    if solicitud is None:
        solicitud = Ruta(ruta=str(request.path))
        db.session.add(solicitud)
        db.session.commit()

    host = Sitio.query.filter_by(sitio=request.host).first()
    if host is None:
        host = Sitio(sitio=request.host)
        db.session.add(host)
        db.session.commit()

    tamano = int(request.headers.get('Content-Length') or 0)

    now = datetime.datetime.now()

    registro = Registro(sitio=host, ruta=solicitud, sesion=sesion, ipaddr=ip, tamano=tamano)
    db.session.add(registro)
    db.session.commit()

    conexion.ultimo = now
    sesion.ultimo = now
    db.session.commit()

    g.ip = ip
    g.user = Ident
    g.sesion = sesion
    g.conexion = conexion
    g.registro = registro
    g.dispositivo = dispositivo
    httpsession['sid'] = g.sesion.id
