"""
Cuchulufm is a series of wrappers for bottle, mako and others and construct a simple headless cms.

Copyright (C) 2023 Antonio de la Rosa Caballero

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
"""

from cuchulu.libraries.db.corefields import PhangoField
from cuchulu.libraries.db.coreforms import PasswordForm
from hmac import compare_digest as compare_hash
#try:
#    import crypt
#except:
#    pass

#import bcrypt
from argon2 import PasswordHasher

class PasswordField(PhangoField):
    """Field for check and save passwords"""
    
    def __init__(self, name, size=1024, required=False):
        
        super(PasswordField, self).__init__(name, size, required)    
        self.protected=True
        self.name_form=PasswordForm
        self.default_value=''
        self.encrypt_password=True
        self.jformat='password'
    
    def check(self, value):
        
        self.txt_error=''
        self.error=False
        
        value.strip()
        
        if value=='':
            
            if self.model!=None:
            
                if self.model.updated==True:
                    self.required=False
                    self.check_blank=True
                    return ""
                else:
                    
                    self.txt_error=self.error_default
                    self.error=True
                    
            else:
                self.txt_error=self.error_default
                self.error=True
            
        else:
            
            #if crypt.METHOD_SHA512 in crypt.methods:
            
            #salt=crypt.mksalt(crypt.METHOD_SHA512)
            if self.encrypt_password:
                #value=crypt.crypt(value)
                ph=PasswordHasher()
                final_value=ph.hash(value)
                return final_value

            """
            else:
                
                self.txt_error="You need the SHA512 method"
                self.error=True
                return ""
            """
        
        return value
    
    @staticmethod
    def verify( password, h):
        """Static method used for verify a password save using PasswordField"""
        #return bcrypt_sha256.verify(password, h)
        #return compare_hash(h, crypt.crypt(password, h))
        ph=PasswordHasher()
        try:
            return ph.verify(h, password)
        except:
            return False

# Old function bcrypt

"""
try:

    from passlib.hash import bcrypt
    from passlib.hash import bcrypt_sha256

    class PasswordField(PhangoField):
        
        def __init__(self, name, size=1024, required=False):
            
            super(PasswordField, self).__init__(name, size, required)    
            self.protected=True
            self.name_form=PasswordForm
            self.default_value=''
        
        def check(self, value):
            
            self.txt_error=''
            self.error=False
            
            value.strip()
            
            if value=='':
                
                if self.model!=None:
                
                    if self.model.updated==True:
                        self.required=False
                        self.check_blank=True
                        return ""
                    else:
                        
                        self.txt_error="The field is empty"
                        self.error=True
                        
                else:
                    self.txt_error="The field is empty"
                    self.error=True
                
            else:
                
                #if crypt.METHOD_SHA512 in crypt.methods:
                
                #value = bcrypt_sha256.encrypt(value)
                value = bcrypt_sha256.hash(value)
            
            return value
        
        @staticmethod
        def verify( password, h):
            
            return bcrypt_sha256.verify(password, h)
    
except:
"""   
