/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package business.user;

import java.time.Instant;
import static java.time.temporal.ChronoUnit.DAYS;
import static java.util.UUID.randomUUID;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import exception.InvalidEmailException;
import model.person.Token;
import model.person.enums.TokenType;
import model.person.Person;

import java.util.Arrays;
import static java.time.Instant.now;

/**
 *
 * @author Patrick
 */
@Stateless
public class TokenManager {

    @PersistenceContext(name = "pu_person")
    private EntityManager em;

    @Inject
    PasswordManager passwordManager;
    
    @Inject
    PersonManager customerManager;
    
    public String generate(final String email, final String ipAddress, final String description,
            final TokenType tokenType) {

        String rawToken = randomUUID().toString();
        Instant expiration = now().plus(14, DAYS);

        save(rawToken, email, ipAddress, description, tokenType, expiration);

        return rawToken;
    }
    
    public String generateFileToken(final String email, final String description) {
        
        String rawToken = randomUUID().toString();
        Instant expiration = now().plus(3, DAYS);
        
        save(rawToken, email, null, description, TokenType.FILE, expiration);

        return rawToken;
    }
    
    public void save(final String rawToken, final String email, final String ipAddress,
            final String description, final TokenType tokenType, final Instant expiration) {

        Person user = this.customerManager.getByEmail(email)
                .orElseThrow(InvalidEmailException::new);

        Token token = new Token();

        token.setTokenHash(Arrays.toString(this.passwordManager.hashToken(rawToken)));
        token.setExpiration(expiration);
        token.setDescription(description);
        token.setTokenType(tokenType);
        token.setIpAddress(ipAddress);

        user.addToken(token);

        this.em.persist(user);
    }
    
    public void remove(String token) {
        this.em.createNamedQuery(Token.REMOVE_TOKEN)
                .setParameter("tokenHash", token).executeUpdate();
    }
    
    public void removeExpired() {
        
        this.em.createNamedQuery(Token.REMOVE_EXPIRED_TOKEN)
                .setParameter("timestamp", Instant.now())
                .executeUpdate();
    }
}
