package riomhaire.lti.core.infrastructure.facades.configuration.clientregistration;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import riomhaire.lti.core.model.configuration.ClientConfiguration;
import riomhaire.lti.core.model.interfaces.UniKeyResolver;

import java.util.Optional;


/**
 * When a tool/partner-lms is registered we need to store this information somewhere ... and we have
 * abstracted this out as a  'ClientRegistrationResolver'. Implementations of this interface  could be
 * to a file, DB or Redis - but all the call wants to know about is I want to find out about this deployment
 * <p>
 * This implementation is for Redis
 */
public class RedisBasedClientRegistrationResolver implements UniKeyResolver<Optional<ClientConfiguration>, String> {
    final ObjectMapper objectMapper = new ObjectMapper();
    private final RedisTemplate<String, String> template;
    // Logger
    private Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * @param template THe spring redis template
     */
    public RedisBasedClientRegistrationResolver(RedisTemplate<String, String> template) {
        this.template = template;
    }

    /**
     * Return the registration information related to this issuer/client-id pair
     *
     * @param key ... This is canvas/blackboard or some other entity
     * @return ClientConfiguration if found
     */
    @Override
    public Optional<ClientConfiguration> lookup(String key) {
        try {
            var hash = DigestUtils.md5DigestAsHex((key).getBytes());
            var actualKey = String.format("lti-client-registration-%s", hash);
            var blob = template.opsForValue().get(actualKey);

            if (blob != null) {
                return Optional.of(objectMapper.readValue(blob, ClientConfiguration.class));
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            // Return not there
        }
        return Optional.empty();
    }
}
