package eu.dnetlib.openaire.user.utils;

import eu.dnetlib.openaire.user.dao.UserVerificationDAO;
import eu.dnetlib.openaire.user.pojos.UserVerification;
import eu.dnetlib.openaire.user.store.DataSourceConnector;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

/**
 * Created by kiatrop on 2/10/2017.
 */
@Component(value = "verificationActions")
public class VerificationActions {

    @Autowired
    private DataSourceConnector dataSourceConnector;

    private Logger logger = Logger.getLogger(VerificationActions.class);

    @Autowired
    private UserVerificationDAO userVerificationDAO;

    /**
     * Adds new row in the verification table
     */
    public void addVerificationEntry(String username, String verificationCode, Timestamp date) {

        try {
            UserVerification userVerification  = new UserVerification(username);
            logger.info("verificationCode: " + verificationCode);
            userVerification.setVerificationCode(verificationCode);
            userVerification.setDate(date);

            userVerificationDAO.insert(userVerification);

            logger.info("Insert user: " + username);

        } catch (SQLException e) {;
            logger.error("Fail to insert user.", e);
        }
    }

    /**
     * Updates the row of verification table with the new date for the given username
     */
    public void updateVerificationEntry(String username, String verificationCode, Timestamp date) {

        try {

            // Get userId to update user
            UserVerification userVerificationOld = userVerificationDAO.fetchByUsername(username);
            UserVerification userVerification  = new UserVerification(username);
            userVerification.setVerificationCode(verificationCode);
            userVerification.setDate(date);
            userVerification.setId(userVerificationOld.getId());

            userVerificationDAO.update(userVerification);

            //logger.info("Update user: " + username + " with verification code " + verificationCode);

        } catch (SQLException e) {
            logger.error("Fail to update user.", e);
        }
    }

    /**
     * Delete a verification with a specific id
     */
    public void deleteVerificationEntry(String username) {

        try {
            UserVerification userVerification  = new UserVerification(username);
            userVerificationDAO.delete(userVerification);
            logger.info("Delete user: " + username);
        } catch (SQLException e) {;
            logger.error("Fail to delete user.", e);
        }
    }

    /**
     * Checks if the verification row exists for the given username
     */
    public boolean verificationEntryExists(String username) {

        try {
            UserVerification userVerification = userVerificationDAO.fetchByUsername(username);

            if (userVerification == null) {
                logger.info("There is no user with username: " + username);
                return false;
            }
            else {
                logger.info("User: " + username + " was found!");
                return true;
            }
        } catch (SQLException e) {
            logger.error("Fail to search user.", e);
        }
        return true;
    }

    /**
     * Checks if the verification row exists for the given username
     */
    public boolean verificationCodeIsCorrect(String username, String verificationCode) {
        
            try {
                UserVerification userVerification = userVerificationDAO.fetchByUsername(username);

                if (userVerification == null) {
                    logger.info("There is no user with username: " + username);
                    return false;
                }
                else {
                    logger.info("User: " + username + " was found!");

                    if (verificationCode.equals(userVerification.getVerificationCode())) {
                        logger.info("Verification Code is correct!");
                        //logger.info("... and verification code: " + verificationCode + " is correct!");
                        return true;
                    }
                }
            } catch (SQLException e) {
                logger.error("Fail to search user.", e);
            }
            return false;
    }

    /**
     * Checks if the verification code has expired
     * !!! Verification code expires in 24hours !!!
     */
    public boolean verificationCodeHasExpired(String username){

        try {
            UserVerification userVerification = userVerificationDAO.fetchByUsername(username);
            LocalDateTime date = userVerification.getDate().toLocalDateTime();

            long nHours = ChronoUnit.HOURS.between(date, LocalDateTime.now());

            if (nHours > (long)24)
                return true;
            else
                return false;

        } catch (SQLException e) {
            logger.error("Fail to search user.", e);
        }
        return true;
    }

    public DataSourceConnector getDataSourceConnector() {
        return dataSourceConnector;
    }

    public void setDataSourceConnector(DataSourceConnector dataSourceConnector) {
        this.dataSourceConnector = dataSourceConnector;
    }
}
