
#from cuchulu import wsgi_app
from cuchulu.libraries.i18n import I18n, PGetText
from cuchulu.libraries.mtemplates import env_theme, PTemplate
from cuchulu.modules.admin2.models.admin import UserAdmin2, LoginTries2, PrivilegesModule2
from cuchulu.libraries.db.webmodel import WebModel
from cuchulu.libraries.db import simplequery
from settings import config
from cuchulu.libraries.datetime import now, format_local_strtime, timestamp_to_datetime, obtain_timestamp
from cuchulu.libraries.keyutils import create_key_encrypt, create_key
from time import time
from cuchulu.wsgiapp import app
#from cuchulu.modules.admin2 import admin_app
from bottle import request, redirect, Bottle, response
from cuchulu.modules.admin2.libraries.loginplugin import check_login
from cuchulu.libraries.sessionplugin import SessionPlugin, Session
from cuchulu.libraries.httputils import GetPostFiles
from cuchulu.libraries.db.formsutils import check_form, csrf_token
from cuchulu.libraries.db.coreforms import PasswordForm
from cuchulu.libraries.sendmail import SendMail
from cuchulu.libraries.db.formsutils import check_csrf
from cuchulu.modules.admin2.libraries.config import modules_admin
from cuchulu.modules.admin2.libraries.check_login_tries import check_login_tries
from cuchulu.modules.admin2 import admin_app

#admin_app=Bottle()
#admin_app.install(SessionPlugin())
#admin_app.install(check_login)

env=env_theme(__file__)
t=PTemplate(env)

gtext=PGetText(__file__)

_=gtext.gettext

usermodel=UserAdmin2()

usermodel.create_forms()

privilegesmodule=PrivilegesModule2()

login_tries=5

if hasattr(config, 'login_tries'):
    login_tries=config.login_tries
    
seconds_login=300

if hasattr(config, 'seconds_login'):
    seconds_login=config.seconds_login
    
cookie_name='cuchulu_session'

if hasattr(config, 'cookie_name'):
    cookie_name=config.cookie_name

admin_folder='/admin'

if hasattr(config, 'admin_folder'):
    admin_folder=config.admin_folder

@admin_app.get('/home', name="admin_app.home_admin")
def home_admin(session):
    
    return t.load_template('layout.phtml', title=_('Admin'), module_selected='home_admin')
    

@app.get(admin_folder) 
def redirect_home():
    
    redirect(app.get_url('admin_app.home_admin'))

@admin_app.get('/login', name="admin_app.login_admin", skip=[check_login])
def login_admin(session=Session()):
    
    db=WebModel.connection()
    
    if cookie_name+'_remember' in request.cookies:
            
            arr_user=simplequery.select(usermodel, db, dict_fields=['id', 'username', 'dark_theme', 'privileges', 'lang'], where_sql='WHERE token_login=%s', dict_values=[request.cookies[cookie_name+'_remember']])
            
            if len(arr_user)>0:
                now_str=now()
                
                date_now=format_local_strtime('YYYY-MM-DD HH:mm:ss', now_str)
                
                db.query('update useradmin2 set last_login=%s WHERE id=%s', [date_now, arr_user[0]['id']])
                
                session['login_admin']=True
                session['user_id']=arr_user[0]['id']
                session['theme']=arr_user[0]['dark_theme']
                session['modules']=get_modules_user(arr_user[0], db)
                session['privileges']=arr_user[0]['privileges']
                session['lang']=arr_user[0]['lang']
                
                session.save()
            
                db.close()
                
                redirect(app.get_url('admin_app.home_admin'))
                
    with db.query('select count(id) as num_users from useradmin2', []) as cursor:
        num_users=cursor.fetchone()['num_users']
        
        if not num_users:
            redirect(app.get_url('admin_app.signup_admin'))
        
    db.close()
    
    #i18n=I18n('admin2')
    
    return t.load_template('login.phtml', title=_('Login'))

@admin_app.get('/signup', skip=[check_login], name='admin_app.signup_admin')
def signup_admin(session=Session()):
    
    db=WebModel.connection()
    
    with db.query('select count(id) as num_users from useradmin2', []) as cursor:
        num_users=cursor.fetchone()['num_users']
        
        if num_users>0:
            redirect(app.get_url('admin_app.login_admin'))
        
    db.close()
    
    #i18n=I18n('admin2')
    
    return t.load_template('signup.phtml', title=_('Signup'))
    
@admin_app.post('/login', skip=[check_login], name='admin_app.check_login_admin')
def check_login_admin(session):
    
    db=WebModel.connection()
    
    #i18n=I18n('admin2')
    
    error=1
    
    message=_('Invalid user and password')
    
    no_login=check_login_tries(request, db)
    
    #username=request.json.get('username', '')
    #password=request.json.get('password', '')
    #remember_login=request.json.get('remember_login', '')
    getpost=GetPostFiles()
    
    getpost.obtain_post()
    
    username=getpost.post.get('username')
    password=getpost.post.get('password')
    remember_login=getpost.post.get('remember_login')
    token_auth=''
    
    if username!='' and password!='' and not no_login:
        
        with db.query('select * from useradmin2 WHERE username=%s', [username]) as cursor:
            result=cursor.fetchone()
            
            if result:
                
                if usermodel.fields['password'].verify(password, result['password']):
                    
                    remember_key=''
                    
                    if remember_login==True:
                        # Send cookies
                        
                        remember_key=create_key_encrypt()
                        
                        timestamp=int(time())+315360000
                        
                        #response.set_cookie(key=cookie_name+'_remember', value=remember_key, expires=timestamp, max_age=315360000, httponly=True, path=config.session_opts['session.path'])
                        response.set_cookie(config.cookie_name+'_remember', remember_key, expires=timestamp, max_age=315360000, path=config.session_opts['session.path'], httponly=True)
                        
                    now_str=now()
                    date_now=format_local_strtime('YYYY-MM-DD HH:mm:ss', now_str)
                    
                    token_auth=''
                    
                    if result['double_auth']:
                        
                        token_auth=create_key(8)
                        session['verify_auth']=True
                        
                        # Send email
                        
                        sendmail=SendMail(ssl=True)
                        
                        sendmail.send(config.portal_email, [result['email']], _('Code for complete login'), _('We send to you a code for activate your account using double authentication:')+"\n"+token_auth, content_type='plain', attachments=[])
                    
                    if result['privileges']==0:
                        with db.query('select module from privilegesmodule2 WHERE user_id=%s', [result['id']]) as cursor:
                            modules_priv=[v['module'] for v in cursor.fetchall()]
                            
                            for k, v in modules_admin.items():
                                if k in modules_priv:
                                    if len(v)>2:
                                        modules_priv+=v[2]                            
                    else:

                        modules_priv=[]
                        for k, v in modules_admin.items():
                            modules_priv.append(k)
                            if len(v)==3:
                                modules_priv+=v[2]
                    
                    modules_priv.append('admin_app.home_admin')
                    modules_priv.append('admin_app.change_theme')
                    
                    db.query('update useradmin2 set token_login=%s, last_login=%s, token_auth=%s WHERE id=%s', [remember_key, date_now, usermodel.fields['password'].check(token_auth), result['id']])
                    
                    session['login_admin']=True
                    session['user_id']=result['id']
                    session['theme']=result['dark_theme']
                    session['modules']=modules_priv
                    session['privileges']=result['privileges']
                    session['lang']=result['lang']
                    error=0
                    message=''
    
    db.close()
    
    return {'error': error, 'message': message, 'no_login': no_login}

@admin_app.post('/signup', skip=[check_login], name='admin_app.signup_insert_admin')
def signup_insert_admin(session=Session()):
    
    #i18n=I18n('admin2')
    
    error=1
    
    message=''
    
    db=WebModel.connection()
    
    arr_form={'username': usermodel.forms['username'], 'password': usermodel.forms['password'], 'repeat_password': PasswordForm('repeat_password', ''), 'email': usermodel.forms['email']}
    
    getpost=GetPostFiles()
    
    getpost.obtain_post()
    
    #Only can exist and user
    
    final_password=getpost.post.get('password', '')
    
    (error, error_form, post, arr_form)=check_form(getpost.post, arr_form, sufix_form='_error')
    
    post['password']=final_password
    
    post['privileges']=2
    
    with db.query('select count(id) as num_users from useradmin2', []) as cursor:
        num_users=cursor.fetchone()['num_users']
        
        if num_users:
            message="You cannot add new users from here"
        else:
            error=0
    
    if not error:
        
        if simplequery.insert(usermodel, db, dict(post)):
        #if 1:
            error=0
            message="User added!"
        else:
            message=_('Sorry, cannot create the new user')
            
    db.close()
    
    return {'error': error, 'message': message}

@admin_app.get('/logout', name="admin_app.logout_admin", skip=[check_login]) 
def logout_admin(session):
    
    if login_admin in session:
        del session['login_admin']
    
    if cookie_name+'_remember' in request.cookies:
        response.delete_cookie(cookie_name+'_remember', path=config.session_opts['session.path'])
        
    redirect(app.get_url('admin_app.login_admin'))
    
@admin_app.get('/change_lang', name='admin_app.change_lang')
def change_lang():
    
    db=WebModel.connection()
    
    error=0
    
    message=''
    
    db.close()
    
    return {'error': error, 'message': message}

@admin_app.get('/change_theme', name="admin_app.change_theme")
def change_theme(session=Session()):
    
    try:
        theme=int(request.query.get('theme', 0))
    except:
        theme=0
    
    error=1

    db=WebModel.connection()
    
    session['theme']=theme
    
    db.query('update useradmin2 set dark_theme=%s WHERE id=%s', [theme, session['user_id']])
    
    error=0
    
    db.close()
    
    return {'error': error, 'message': ''}

@admin_app.get('/need_auth', skip=[check_login], name='admin_app.need_auth')
def need_auth(session=Session()):
    
    #i18n=I18n('admin2')
    
    return t.load_template('need_auth.phtml', title=_('Auth check'))

@admin_app.post('/auth_check', skip=[check_login], name='admin_app.auth_check')
def auth_check(session=Session()):

    error=1
    
    #check_csrf()
    
    you_cannot_login=0
    
    db=WebModel.connection()
    
    if 'login_admin' in session:
        
        code=request.forms.get('code', '')
        
        user_admin=UserAdmin2(db)
        
        user_admin.check_user=False
        
        arr_user=user_admin.set_conditions('WHERE id=%s', [session.get('user_id', 0)]).select_a_row_where()
        #print(arr_user)
        if arr_user:
            
            if user_admin.fields['token_auth'].verify(code, arr_user['token_auth']):
            
                user_admin.safe_query()
                
                #user_admin.set_conditions('WHERE id=%s', [session['user_id']]).update({'token_auth': ''})
                user_admin.query('update useradmin2 set token_auth="" WHERE id=%s', [session['user_id']])
                
                session['verify_auth']=False
                error=0
                
            else:
            
                #you_cannot_login=check_login_tries()
                you_cannot_login=check_login_tries(request, db)
                
        else:
            
            you_cannot_login=check_login_tries()
    
    db.close()
    
    return {'error': error, 'you_cannot_login': you_cannot_login}

"""
def check_login_tries(request, db):
    
    logintries=LoginTries2(db)
    
    logintries.safe_query()
    
    ip=request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')

    you_cannot_login=0
    
    now_str=now()
    date_now=format_local_strtime('YYYY-MM-DD HH:mm:ss', now_str)
    
    date_check=format_local_strtime('YYYY-MM-DD HH:mm:ss', timestamp_to_datetime(obtain_timestamp(now_str)-seconds_login))
    
    logintries.query('delete from logintries2 where last_login<%s', [date_check])
    
    arr_try=logintries.set_conditions('WHERE ip=%s', [ip]).select_a_row_where()
    
    if arr_try:
        
        if arr_try['num_tries']<login_tries:
        
            logintries.query('update logintries2 set num_tries=num_tries+1, last_login=%s WHERE ip=%s', [date_now, ip])
            
        else:
            
            you_cannot_login=1
            
    else:
        
        logintries.query('insert into logintries2 (`ip`, `num_tries`, `last_login`) VALUES (%s, %s, %s)', [ip, 1, date_now])

    return you_cannot_login
"""

#app.mount(admin_folder, admin_app)

def get_modules_user(arr_user, db):
    
    if arr_user['privileges']==0:
        with db.query('select module from privilegesmodule2 WHERE user_id=%s', [arr_user['id']]) as cursor:
            modules_priv=[v['module'] for v in cursor.fetchall()]
            
            for k, v in modules_admin.items():
                if k in modules_priv:
                    if len(v)>2:
                        modules_priv+=v[2]                            
    else:

        modules_priv=[]
        for k, v in modules_admin.items():
            modules_priv.append(k)
            if len(v)==3:
                modules_priv+=v[2]
    
    modules_priv.append('admin_app.home_admin')
    
    return modules_priv
