package org.gluu.service.cache;

import com.google.common.collect.Sets;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Protocol;

import java.io.Serializable;
import java.util.Set;

/**
 * Important : keep it weld free. It's reused by oxd !
 *
 * @author Yuriy Zabrovarnyy
 */
public class RedisSentinelProvider extends AbstractRedisProvider {

    private static final Logger LOG = LoggerFactory.getLogger(RedisSentinelProvider.class);

    private JedisSentinelPool pool;

    public RedisSentinelProvider(RedisConfiguration redisConfiguration) {
        super(redisConfiguration);
    }

    public void create() {
        try {
            LOG.debug("Starting RedisSentinelProvider ... configuration:" + getRedisConfiguration());

            JedisPoolConfig poolConfig = createPoolConfig();
            String password = redisConfiguration.getPassword();
            pool = new JedisSentinelPool(
                    getRedisConfiguration().getSentinelMasterGroupName(),
                    Set.of(StringUtils.split(getRedisConfiguration().getServers().trim(), ",")),
                    poolConfig,
                    redisConfiguration.getConnectionTimeout(),
                    redisConfiguration.getSoTimeout(),
                    password,
                    Protocol.DEFAULT_DATABASE);
            testConnection();
            LOG.debug("RedisSentinelProvider started.");
        } catch (Exception e) {
            LOG.error("Failed to start RedisSentinelProvider.");
            throw new IllegalStateException("Error starting RedisSentinelProvider", e);
        }
    }

    public void destroy() {
        LOG.debug("Destroying RedisSentinelProvider");

        try {
            pool.close();
        } catch (Exception e) {
            LOG.error("Failed to destroy RedisSentinelProvider", e);
            return;
        }

        LOG.debug("Destroyed RedisSentinelProvider");
    }

    @Override
    public JedisSentinelPool getDelegate() {
        return pool;
    }

	@Override
	public boolean hasKey(String key) {
        try (final Jedis resource = pool.getResource()) {
            Boolean hasKey = resource.exists(key);

            return Boolean.TRUE.equals(hasKey);
        }
	}

    @Override
    public Object get(String key) {
        try (final Jedis resource = pool.getResource()) {
            byte[] value = resource.get(key.getBytes());
            Object deserialized = null;
            if (value != null && value.length > 0) {
                deserialized = SerializationUtils.deserialize(value);
            }
            return deserialized;
        }
    }

    @Override
    public void put(int expirationInSeconds, String key, Object object) {
        try (final Jedis resource = pool.getResource()) {
            String status = resource.setex(key.getBytes(), expirationInSeconds, SerializationUtils.serialize((Serializable) object));
            LOG.trace("put - key: " + key + ", status: " + status);
        }
    }

    @Override
    public void put(String key, Object object) {
        try (final Jedis resource = pool.getResource()) {
            String status = resource.set(key.getBytes(), SerializationUtils.serialize((Serializable) object));
            LOG.trace("put - key: " + key + ", status: " + status);
        }
    }

    @Override
    public void remove(String key) {
        try (final Jedis resource = pool.getResource()) {
            Long entriesRemoved = resource.del(key.getBytes());
            LOG.trace("remove - key: " + key + ", entriesRemoved: " + entriesRemoved);
        }
    }

    @Override
    public void clear() {
        try (final Jedis resource = pool.getResource()) {
            resource.flushAll();
            LOG.trace("clear");
        }
    }
}

@@ -37,40 +37,53 @@
 ort 
-com.google.common.collect
+java.io.Serializable;%0Aimport java.util
 .Set
-s
 ;%0A
+%0A
 impo
@@ -230,16 +230,17 @@
 actory;%0A
+%0A
 import r
@@ -355,16 +355,16 @@
 elPool;%0A
+
 import r
@@ -397,60 +397,8 @@
 l;%0A%0A
-import java.io.Serializable;%0Aimport java.util.Set;%0A%0A
 /**%0A

remove wrong imports