from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from naver_config import NaverConfig


class Persistence(NaverConfig):
    myApp = Flask(__name__)

    def __init__(self, myApp, session=None):
        super().__init__(myApp, session)
    """
       Métodos SQL Core 
    """
# TESTED

    def _sql(self, rawSql, sqlVars={}):
        self.myDb = SQLAlchemy(self.myApp)
        assert type(rawSql) == str
        assert type(sqlVars) == dict
        res = self.myDb.session.execute(rawSql, sqlVars)
        self.myDb.session.commit()
        return res
# TESTED

    def _sqltran(self, rawSql, sqlVars={}):
        self.myDb = SQLAlchemy(self.myApp)
        assert type(rawSql) == str
        assert type(sqlVars) == dict
        cursor = self.myDb.session.execute(rawSql, sqlVars)
        session = self.myDb.session
        return {"cursor": cursor, "session": session}
    """
       SETTERS
    """
# TESTED

    def setWrite(self, stm, table, logtable="log", loglevel=1, logtype=1):
        self.core.getEnvCnx(table)
        res = self._sqltran(stm)
        if res is not None:
            self.setWriteLog(stm, logtable, loglevel, logtype)
        return res
# TESTED

    def setWriteLog(self, stm, logtable="log", loglevel=1, logtype=1):
        insert = "INSERT INTO " + logtable + """(description,log_level_id_fk,log_type_id_fk,user_id_fk)
             VALUES ('""" + str(stm) + "#"+str(self.mySession)+"',"+str(loglevel)+","+str(logtype)+","+str(self.mySession[0])+")"
        self.core.getEnvCnx(logtable)
        res = self._sqltran(insert)
        return res

    def spExec(self, sp, args):
        stm = "CALL "+sp+"("+args+")"
        return self._sql(stm)

    def setProp(self, table, key, value, condition):
        if condition:
            stm = "UPDATE "+table+" SET props = jsonb_set(props, "+key+", '"+value+"' ,false) \
                FROM "+table+" \
                WHERE "+condition+""
            return self._sql(stm)
    """
       GETTERS
    """

    def getPaginatedQuery(self, stm, table, field, since, top):
        condition = (lambda x: "AND"
                     if (str(x).upper().contains("WHERE")) else "WHERE")(stm)
        pStm = stm+" "+condition+" "+field+" > "+since + " LIMIT "+top
        res = self.getQuery(pStm, table)
        return res
# TESTED

    def getProps(self, table, condition="1=1"):
        stm = "SELECT props from public.\""+table+"\" Where "+condition
        print(stm)
        res = self.getQuery(stm, table)
        return res[0]['props']
# TESTED

    def getNextVal(self, field, table):
        stm = "SELECT MAX("+field+") FROM "+table+""
        res = self.getQuery(stm, table)
        return res[0]
# TESTED

    def getUserPermission(self, userid, table='permission'):
        stm = """ SELECT prm.* FROM public.\""""+table + """\" prm 
                JOIN public.\"profile\" prf 
                ON prm.profile_id_fk = prf.id 
                JOIN public.\"profile_user\" prfUsr
                ON prfUsr.profile_id_fk = prf.id
                JOIN public.\"user\" usr 
                ON  prfUsr.user_id_fk =usr.id
                WHERE  usr.id = """ + userid
        res = self.getQuery(stm, table)
        return res
# TESTED

    def getParam(self,  session, table='param',  key=None,):
        stm = """SELECT prm.* FROM
               public.\"""" + table + """\" prm 
                JOIN public.\"param_institution\" prmInst 
                ON prmInst.param_id_fk=prm.id
                JOIN public.\"institution\" ins 
                ON ins.id = prmInst.institution_id_fk
                WHERE ins.id = """+session[0]+(lambda x: " AND prm.key="+key if (x is not None) else "")(key)
        res = self.getQuery(stm, table)
        return res
# TESTED

    def getQuery(self, stm, table):
        self.core.getEnvCnx(table)
        res = self._sql(stm)
        ls = []
        for row in res:
            ls.append(dict(row))
        return ls
    """
       Métodos GET ENV
    """
