package eu.dnetlib.openaire.user.ldap;

import com.unboundid.ldap.sdk.*;
import eu.dnetlib.openaire.user.LDAPUser;
import eu.dnetlib.openaire.user.MigrationUser;
import eu.dnetlib.openaire.user.Role;
import eu.dnetlib.openaire.user.dao.RoleDAO;
import eu.dnetlib.openaire.user.dao.SQLMigrationUserDAO;
import eu.dnetlib.openaire.user.store.LDAPConnector;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.SQLException;

/**
 * Created by sofia on 7/11/2016.
 */
public class MUserActionsLDAP {

    @Autowired
    private LDAPConnector ldapConnector;

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

    public  boolean authenticate(String cn, String password) throws LDAPException {
        LDAPConnection connection = ldapConnector.getConnection();
        String usersDN = ldapConnector.getUsersDN();

        try {
            logger.debug("checking if user " + cn + " entered a correct password when logging in");

            Filter filter = Filter.createEqualityFilter("cn", cn);

            SearchRequest searchRequest = new SearchRequest(usersDN, SearchScope.SUB, filter, "userPassword");
            SearchResult searchResult = connection.search(searchRequest);

            for (SearchResultEntry entry : searchResult.getSearchEntries()) {
                if (Joomla15PasswordHash.check(password, entry.getAttributeValue("userPassword")))
                    return true;
            }

            return false;
        }
        finally {
            if (connection != null)
                connection.close();
        }
    }

    public boolean usernameExists(String username) throws LDAPException
    {

        logger.debug("checking if username " + username + " exists");
        LDAPConnection connection = ldapConnector.getConnection();
        String usersDN = ldapConnector.getUsersDN();

        try {
            logger.debug("checking if username " + username + " exists");

            Filter filter = Filter.createEqualityFilter("cn", username);

            SearchRequest searchRequest = new SearchRequest(usersDN, SearchScope.SUB, filter, "cn");
            SearchResult searchResult = connection.search(searchRequest);

            if (!searchResult.getSearchEntries().isEmpty()) {
                logger.debug("User exists.");
                return true;
            }
            logger.debug("User does not exist.");
            return false;
        }
        finally {
            if (connection != null)
                connection.close();
        }
    }

    public boolean authenticateUser(String email, String password) throws LDAPException {
        LDAPConnection connection = ldapConnector.getConnection();
        String usersDN = ldapConnector.getUsersDN();

        try {
            logger.debug("checking if user " + email + " entered a correct password when logging in");
            Filter filter = Filter.createEqualityFilter("mail", email);

            SearchRequest searchRequest = new SearchRequest(usersDN, SearchScope.SUB, filter, "userPassword");
            SearchResult searchResult = connection.search(searchRequest);

            for (SearchResultEntry entry : searchResult.getSearchEntries()) {
                if (Joomla15PasswordHash.check(password, entry.getAttributeValue("userPassword")))
                    logger.debug("User exists.");
                    return true;
            }

            logger.debug("User does not exist.");
            return false;
        }
        finally {
            if (connection != null)
                connection.close();
        }
    }

    public String getRole(String email, String password) throws LDAPException, SQLException {

        boolean authenticated = authenticateUser(email, password);

        if (authenticated)
        {
            SQLMigrationUserDAO muDAO = new SQLMigrationUserDAO();
            MigrationUser mUser = new MigrationUser();
            mUser = muDAO.fetchByEmail(email);
            RoleDAO roleDAO = new RoleDAO();
            Role role = roleDAO.fetchById(mUser.getRoleId());
            return role.getRole();
        }
        return null;
    }

    public LDAPUser getUser(String username) throws LDAPException {

        LDAPConnection connection = ldapConnector.getConnection();
        String usersDN = ldapConnector.getUsersDN();

        try {

            logger.debug("getting user " + username + " from ldap");
            Filter filter = Filter.createEqualityFilter("cn",username);
            SearchRequest searchRequest =
                    new SearchRequest(usersDN, SearchScope.SUB, filter, "mail", "displayName", "cn");

            SearchResult searchResult = connection.search(searchRequest);
            LDAPUser user = new LDAPUser();

            for (SearchResultEntry entry : searchResult.getSearchEntries()) {
                user.setCn(entry.getAttributeValue("cn"));
                user.setEmail(entry.getAttributeValue("mail"));
                user.setDisplayName(entry.getAttributeValue("displayName"));
            }
            logger.debug("Cn = " + user.getCn() + " mail = " + user.getEmail() + " displayName = " + user.getDisplayName());
            return user;

        } finally {
            if (connection != null)
                connection.close();
        }
    }

}