package ovh.herisson.Clyde.Services;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.TokenRepository;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;

@Service
public class TokenService {
    private final TokenRepository tokenRepo;

    public TokenService(TokenRepository tokenRepo){
        this.tokenRepo = tokenRepo;
    }

    public Iterable<Token> getAllTokens() {
        return tokenRepo.findAll();
    }


    public String generateNewToken(){
        byte[] bytes = new byte[64];
        new SecureRandom().nextBytes(bytes);
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (((bytes[i]+256)%256  %95+ 32));
        }
        // will never end up in the catch because of the way that SecureRandom.nextBytes is implemented
        try {
            return new String(Base64.getEncoder().encode(bytes),"ISO_8859_1");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public User getUserFromToken(String token) {
        Token tokenRep = tokenRepo.getByToken(token);
        if (tokenRep == null)
            return null;

        return tokenRep.getUser();
    }

    public void saveToken(Token token){
        //Si l'utilisateur a déja 5 token delete celui qui devait expirer le plus vite
        ArrayList<Token> tokenList = tokenRepo.getByUserOrderByExpirationDate(token.getUser());

        while(tokenList.size() >= 5){
            tokenRepo.delete(tokenList.getFirst());
            tokenList.remove(tokenList.getFirst());
        }
        tokenRepo.save(token);
    }

    //Tous les jours a minuit
    @Scheduled(cron = "0 0 0 * * ?")
    public void autoDeleteToken() {
        for (Token t: tokenRepo.findAll()){
            Calendar cal = Calendar.getInstance();

            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(t.getExpirationDate());

            if (cal.compareTo(cal2) >= 0){
                tokenRepo.delete(t);
            }
        }
    }
}
