package com.r11.tools.config;

import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import redis.clients.jedis.JedisPool;

/**
 * Class containing configuration for Redis db client
 * @author Rafał Żukowicz
 */
@Configuration
@EnableRedisRepositories
@PropertySource("classpath:data-access.properties")
public class RedisConfig {

    @Autowired
    private Environment environment;

    /**
     * Bean of JedisPool - the Redis client. It stores requests in "the pool" and then fires them at Redis.
     * It's considered super lightweight and fast client variant
     * @return lightweight client of the Redis - the JedisPool
     */
    @Bean
    JedisPool jedisPool(){
        final JedisPool pool = new JedisPool(environment.getProperty("redis.host"),
                Integer.parseInt(environment.getProperty("redis.port")));
        return pool;
    }

    /**
     * Bean of a factory for connenction object.
     * It's initialized with Redis db url property and is fed to other methods.
     * @return the factory for RedisTemplates
     */
    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration =
                new RedisStandaloneConfiguration(Objects.requireNonNull(environment.getProperty("redis.host")),
                        Integer.parseInt(Objects.requireNonNull(environment.getProperty("redis.port"))));
        return new JedisConnectionFactory(redisStandaloneConfiguration);
    }

    /**
     * RedisTemplate is the tool to store and retrieve given type (object) of hash from the database.
     * It's like you could store your Java object by just naming it inside database. You might thing about it
     * as of DAO.
     * @return RedisTemplate the redis dao.
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.setExposeConnection(true);
        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }

}
