#!/usr/bin/python
# -*- coding: UTF-8 -*-

import functools

from flask import session
from flask import redirect, abort, url_for
from flask import request

import config
from functions import redis_cache

def session_field_required( field, value ):
    def decorator( func ):
        @functools.wraps( func )
        def wrapper_login_required( *args, **kwargs ):
            if not field in session:
                return redirect( url_for( "login.login" ) + "?" + request.path )
            
            elif not session.get( field ) == value:
                return redirect( url_for( "login.login" ) + "?" + request.path )
            
            return func( *args, **kwargs )
    
        return wrapper_login_required
    
    return decorator

def login_required( func ):
    @functools.wraps( func )
    def wrapper_login_required( *args, **kwargs ):
        if not session.get( "logged", False ) :
            return redirect( url_for( "login.login" ) + "?" + request.path )
        
        return func( *args, **kwargs )

    return wrapper_login_required

def referer_required( func ):
    @functools.wraps( func )
    def wrapper_login_required( *args, **kwargs ):
        if not request.headers.get( "Referer", False ):
            return "referrer needed", 404
        
        return func( *args, **kwargs )

    return wrapper_login_required

def admin_required( func ):
    @functools.wraps( func )
    def wrapper_login_required( *args, **kwargs ):
        if not session.get( "logged", False ) or not session.get( "account_type_name", None ) == "Administrator":
            return redirect( url_for( "login.login" ) + "?" + request.path )
        
        return func( *args, **kwargs )

    return wrapper_login_required

@redis_cache( 15 * 60 )
def check_correct_submitter( submission_id, submitter_id ):
    sql = """
        SELECT count( * )
        FROM submissions
        WHERE uuid = %s AND submitter_id = %s
    """
    check = config.db.query_fetchone( sql, ( submission_id, submitter_id, ) )[ "count" ]
    return check == 1

def submission_has_access( func ):
    @functools.wraps( func )
    def wrapper_login_required( *args, **kwargs ):
        submission_id = request.view_args.get( "submission_id", None )
        user_id = session.get( "user_id" )
        
        if session.get( "account_type_name", None ) == "Administrator":
            return func( *args, **kwargs )
        
        elif not session.get( "logged", False ) or not session.get( "account_type_name", None ) == "Submitter":
            return redirect( url_for( "login.login" ) + "?" + request.path )
        
        elif submission_id != None and not check_correct_submitter( submission_id, user_id ):
            return abort( 403 )
        
        else:
            return func( *args, **kwargs )

    return wrapper_login_required

def trainer_has_access( func ):
    @functools.wraps( func )
    def wrapper_trainer_has_access( *args, **kwargs ):
        if session.get( "account_type_name", None ) == "Administrator":
            return func( *args, **kwargs )
        
        elif not session.get( "logged", False ) or not session.get( "account_type_name", None ) == "Trainer":
            return redirect( url_for( "login.login" ) + "?" + request.path )
        
        else:
            return func( *args, **kwargs )

    return wrapper_trainer_has_access

