package org.gcube.keycloak.avatar;

import java.io.InputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.GET;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.gcube.keycloak.avatar.storage.AvatarStorageProvider;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.keycloak.common.ClientConnection;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;

public class AvatarAdminResource extends AbstractAvatarResource {

    @Context
    private AvatarStorageProvider avatarStorageProvider;

    @Context
    private HttpHeaders httpHeaders;

    @Context
    private ClientConnection clientConnection;

    public AvatarAdminResource(KeycloakSession session) {
        super(session);
//        tokenManager = new TokenManager();
    }

    public void init() {
        checkRealmAdmin();
    }

    @GET
    @Path("/{user_id}")
    @Produces({ "image/png", "image/jpeg", "image/gif" })
    public Response downloadUserAvatarImage(@PathParam("user_id") String userId) {
        try {
            UserModel user = session.users().getUserById(session.getContext().getRealm(), userId);
            return fetchAndCreateResponse(session.getContext().getRealm(), user);
        } catch (ForbiddenException e) {
            return Response.status(Response.Status.FORBIDDEN).entity(e.getMessage()).build();
        } catch (Exception e) {
            logger.error("error getting user avatar", e);
            return Response.serverError().entity(e.getMessage()).build();
        }
    }

    @POST
    @NoCache
    @Path("/{user_id}")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadUserAvatarImage(@PathParam("user_id") String userId, MultipartFormDataInput input) {
        try {
            if (auth == null) {
                return Response.status(Response.Status.UNAUTHORIZED).build();
            }

            RealmModel realm = session.getContext().getRealm();
            UserModel user = session.users().getUserById(session.getContext().getRealm(), userId);

            InputStream imageInputStream = input.getFormDataPart(AVATAR_IMAGE_PARAMETER, InputStream.class, null);
            saveUserImage(realm, user, imageInputStream);
        } catch (ForbiddenException e) {
            return Response.status(Response.Status.FORBIDDEN).entity(e.getMessage()).build();
        } catch (Exception e) {
            logger.error("error saving user avatar", e);
            return Response.serverError().entity(e.getMessage()).build();
        }

        return Response.ok().build();
    }

    private void checkRealmAdmin() {
        if (auth == null) {
            throw new NotAuthorizedException("Bearer");
        } else if (auth.getToken().getRealmAccess() == null
                || !auth.getToken().getRealmAccess().isUserInRole("admin")) {

            throw new ForbiddenException("Does not have realm admin role");
        }
    }
}
