package fyloz.trial.ColorRecipesExplorer.services;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import fyloz.trial.ColorRecipesExplorer.ColorRecipesExplorerApplication;
import fyloz.trial.ColorRecipesExplorer.model.BeanModel;
import org.slf4j.Logger;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public abstract class GenericService<T extends BeanModel> implements IGenericService<T> {

    protected Logger logger = ColorRecipesExplorerApplication.logger;

    protected JpaRepository<T, Integer> dao;

    public GenericService(JpaRepository<T, Integer> dao) {
        this.dao = dao;
    }

    @Override
    public T getByID(int id) {
        return dao.findById(id).get();
    }

    @Override
    public List<T> getAll() {
        return dao.findAll();
    }

    @Override
    public T save(T entity) {
        if (isValidForCreation(entity)) {
            return dao.save(entity);
        }

        return null;
    }

    @Override
    public boolean saveAll(List<T> entities) {
        for (T e : entities) {
            if (save(e) == null) {
                return false;
            }
        }

        return true;
    }

    @Override
    public T update(T entity) {
        if (exists(entity)) {
            return dao.save(entity);
        }

        return null;
    }

    @Override
    public boolean delete(T entity) {
        if (exists(entity)) {
            dao.delete(entity);
            return true;
        }

        return false;
    }

    @Override
    public boolean deleteAll(List<T> entities) {
        for (T e : entities) {
            if (!delete(e)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Vérifie si une entité est valide pour la création dans la base de données.
     *
     * @param entity L'entité à vérifier.
     * @return Si l'entité est valide pour la création.
     */
    public boolean isValidForCreation(T entity) {
        return entity != null && !exists(entity);
    }

    /**
     * Vérifie si une entité existe dans la base de données.
     *
     * @param entity L'entité à vérifier
     * @return Si l'entité existe.
     */
    @Override
    public boolean exists(T entity) {

        return dao.findById(entity.getID()).isPresent();
    }

    /**
     * Transforme un objet en Json.
     *
     * @param obj L'objet à transformer
     * @return L'objet sous forme de Json.
     */
    public String asJson(Object obj) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error("Une erreur est survenue lors de la transformation d'un objet en Json", e);
            return null;
        }
    }
}
