package org.gcube.keycloak.avatar.storage.userattribute;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

import org.apache.commons.io.IOUtils;
import org.gcube.keycloak.avatar.storage.AvatarStorageProvider;
import org.jboss.logging.Logger;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;

public class UserAttributeAvatarStorageProvider implements AvatarStorageProvider {

    private static final Logger logger = Logger.getLogger(UserAttributeAvatarStorageProvider.class);

    private final String userAttribute;

    public UserAttributeAvatarStorageProvider() {
        this(UserAttributeAvatarStorageProviderFactory.USER_ATTRIBUTE_NAME);
    }

    public UserAttributeAvatarStorageProvider(String userAttribute) {
        this.userAttribute = userAttribute;
    }

    @Override
    public void saveAvatarImage(RealmModel realm, UserModel user, InputStream input) {
        logger.debugf("Saving avatar image to user attribute: %s", userAttribute);
        user.setSingleAttribute(userAttribute, getBase64EncodedString(input));
    }

    private String getBase64EncodedString(InputStream input) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            IOUtils.copy(input, baos);
        } catch (IOException e) {
            logger.error("Getting image stream as bytes array", e);
        }
        return Base64.getEncoder().encodeToString(baos.toByteArray());
    }

    @Override
    public InputStream loadAvatarImage(RealmModel realm, UserModel user) {
        logger.debugf("Getting avatar image from user attribute: %s", userAttribute);
        return toBinaryStream(user.getFirstAttribute(userAttribute));
    }

    private InputStream toBinaryStream(String base64EncodedImage) {
        return base64EncodedImage != null ?
                new ByteArrayInputStream(Base64.getDecoder().decode(base64EncodedImage)) : null;
    }

    @Override
    public void deleteAvatarImage(RealmModel realm, UserModel user) {
        logger.debugf("Removing avatar image user's attribute: %s", userAttribute);
        user.removeAttribute(userAttribute);
    }

    @Override
    public void close() {
        // NOOP
    }

}
