package mx.gob.jumapacelaya.Services;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class ValidaLDAPUsuario {

    private static final Logger logger = LoggerFactory.getLogger(ValidaLDAPUsuario.class);

    @Value("${spring.ldap.url}")
    private String ldapUrl;
    
    @Value("${spring.ldap.base}")
    private String ldapBase;
                
    public boolean autenticar(String username, String password) {
        LdapContext ctx = null;
        if (ldapUrl == null|| ldapUrl.trim().isEmpty()){ldapUrl="ldap://svradmin.jumapacelaya.gob.mx:389";}
        if (ldapBase == null || ldapBase.trim().isEmpty()){ldapBase="dc=jumapacelaya,dc=gob,dc=mx";}

        try {
            logger.info("Iniciando rutina autenticar con la URL ["+ldapUrl+"]..");
            Hashtable<String, String> env = new Hashtable<>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, username + "@jumapacelaya.gob.mx");
            env.put(Context.SECURITY_CREDENTIALS, password);
            env.put(Context.PROVIDER_URL, ldapUrl);
            
            logger.info("Autenticando al usuario ["+env.get(Context.SECURITY_PRINCIPAL)+"]");
            
            ctx = new InitialLdapContext(env, null);
            logger.info("Inicializando Contexto para realizar la busqueda..");
            
            // Búsqueda de atributos del usuario
            String searchFilter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
            String searchBase = ldapBase;
                
            logger.info("Preparando la busqueda..");
            SearchControls searchControls = new SearchControls();
            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            searchControls.setReturningAttributes(new String[]{"sAMAccountName", "memberOf", "mail", "givenName", "sn"});
            
            NamingEnumeration<SearchResult> results = ctx.search(searchBase, searchFilter, searchControls);

            logger.info("Busqueda terminada..");
            
            if (results.hasMore()) {
                SearchResult result = results.next();
                Attributes attrs = result.getAttributes();
                // Procesar atributos y crear objeto de respuesta
                logger.info("Usuario encontrado, regresando informacion..");
                return true;
            }
            
            logger.info("No se encontro el usuario..");
            return false;
        } catch (NamingException e) {
            // La autenticación falló o hubo un error
            logger.error("Error de autenticacion..");
            return false;
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                    logger.info("Cierre de Contexto Terminado..");
                } catch (NamingException e) {
                    // Manejar error de cierre
                    logger.error("Error de autenticacion..");
                    //return false;
                }
            }
        }
    }
}
