def __init__(self):
     '''
     AccountManager(...)
     '''
     self.contas = []
     self.usuario = None 
     self.gui = AccountManagerGUI()
     self.gui.setApp(self)
     self.gui.setupUi()
     self.conexao = Conexao()      
     self.logged = False
class AccountManager():
    '''
    Classe AccountManager'''

    def __init__(self):
        '''
        AccountManager(...)
        '''
        self.contas = []
        self.usuario = None 
        self.gui = AccountManagerGUI()
        self.gui.setApp(self)
        self.gui.setupUi()
        self.conexao = Conexao()      
        self.logged = False


    def deleteConta(self,conta):
        '''
        Método para deletar conta da DB
            :param conta: Conta para ser deletada
            :type conta: py:class: `Conta` 
        '''
        self.conexao.session.delete(conta)
        self.conexao.session.commit()


    def deleteUser(self):
        '''
        Método para deletar usuario da DB 
        '''
        self.conexao.session.delete(self.usuario)
        self.conexao.session.commit()
        for conta in self.conexao.session.query(Conta).filter \
                    (Conta.usuario_id==self.usuario.login).all():
            self.conexao.session.delete(conta)
            self.conexao.session.commit()


    def editConta(self,conta):
        '''
        Método para editar conta na DB
            :param conta: Conta para ser editada
            :type conta: py:class: `Conta`
        '''
        aux =  self.conexao.session.query(Conta).filter(Conta.id==conta.id).first()
        aux.nome = conta.nome
        aux.login = conta.login
        aux.senha = conta.senha
        aux.host = conta.host
        aux.tipo = conta.tipo
        self.conexao.session.commit()


    def editUser(self):
        '''
        Método para editar usuario na DB
        '''
        aux =  self.conexao.session.query(Usuario).filter(Usuario.login==self.usuario.login).first()
        aux.nome = self.usuario.nome
        aux.foto = self.usuario.foto
        hash_senha = bcrypt.hashpw(self.usuario.senha, bcrypt.gensalt())
        aux.senha = hash_senha
        self.conexao.session.commit()


    def exit(self):
        '''
        Método para sair do sistema
        '''
        print("Saindo......")
        sys.exit()     


    def getContaAll(self):
        '''
        Método para retorna todas as contas do Usuario guardada na DB
            :param usuario: Usuario logado no sistema
            :type usuario: py:class: `Usuario`
            return: Lista de contas
            rtype: list 
        '''
        if self.isLogged and self.usuario is not None:
            contas = self.conexao.session.query(Conta).filter \
                    (Conta.usuario_id==self.usuario.login).all()   
            contas.sort()
            return contas      


    def insertConta(self,conta):
        '''
        Método para inserir conta na DB
            :param conta: Conta para salvar
            :type conta:py:class: `Conta`
            return: Retorna True se a conta foi inserido senão retorna False
            rtype: boolean 
        '''
        if isinstance(conta,Conta):
            self.conexao.session.add(conta)
            self.conexao.session.commit()
            return True
        else:
            return False      


    def insertUser(self,usuario):
        '''
        Método para inserir Usuario na DB
            :param usuario: Usuario para salvar
            :type usuario:py:class: `Usuario`
            return: Retorna True se usuario foi inserido senão retorna False
            rtype: boolean       
        '''
        if isinstance(usuario,Usuario):
            hash_senha = bcrypt.hashpw(usuario.senha, bcrypt.gensalt())
            usuario.senha = hash_senha
            self.conexao.session.add(usuario)
            self.conexao.session.commit()
            return True
        else:
            return False   


    def isLogged(self):
        '''
        Método que verifica se existe Usuario logado no sistema
            return: Retorna True se houver Usuario logado senão retorna False
            rtype: boolean 
        '''
        if self.logged:
            return True  
        else:
            return False 


    def isLoginFree(self,login):
        '''
        Método para verificar se o login está disponivel para um novo Usuario
            :param login: Login para ser verificado
            :type login: str 
            return: Retorna True se o login estiver disponivel senão retorna False
            rtype: boolean 
        '''
        if self.conexao.session.query(Usuario).filter(Usuario.login==login).all(): 
            return False
        else:
            return True   


    def isSenhaValida(self,senha_digitada,hash_senha):
        '''
        Método para verificar se a senha é válida
            :param senha_digitada: Senha digitada pelo Usuario
            :type senha_digitada: str 
            :param hash_senha: Senha encryptada guardada na DB
            :type hash_senha: str
            return: Retorna True ou False   
            rtype: boolean 
        '''
        return bcrypt.hashpw(senha_digitada,hash_senha) == hash_senha   


    def isValidNewUser(self,nome,login,senha,email):
        '''
        Método que verifica se o Usuario é válido para inserir na DB
            :param nome: Nome do Usuario
            :type nome: str
            :param login: Login do Usuario
            :type login: str
            :param senha: Senha do Usuario
            :type senha: str
            return: Retorna True or False
            rtype: boolean
        '''
        if (self.isLoginFree(login) and len(login) >= 8 \
                     and len(senha) >= 6 and len(nome) >= 3 and '@' in email and len(email) > 6):
            return True
        else:
            return False   


    def login(self,usuario):
        '''
        Método para logar Usuario no sistema
            :param usuario: Usuario autenticado para logar no sistema
            :type usuario: py:class: `Usuario`
        '''
        self.usuario = usuario
        self.contas = self.getContaAll()
        self.logged = True      


    def logout(self):
        '''
        Método para deslogar Usuario do sistema
        '''
        self.logged = False
        self.usuario = None
        self.contas.clear() 


    def qtdContas(self):
        '''
        Método quatidade de contas
            return: Quantidade de contas
            rtype: int 
        '''
        return len(self.contas)


    def userAuth(self,login,senha):
        '''
        Método para autorizar login no sistema
            :param login: Login do Usuario
            :type login: str
            :param senha: Senha do Usuario 
            :type senha: str 
            return: Retorna Usuario se o Usuario foi autenticado senão retorna None
            rtype: py:class: `Usuario` ou None 
        '''      
        usuario = self.conexao.session.query(Usuario).filter \
                (Usuario.login==login).first()
        if isinstance(usuario,Usuario):
            hash_senha = usuario.senha
            if self.isSenhaValida(senha,hash_senha):
                return usuario
            else:
                return None
        else:
            return None