/**
 *
 */
package com.braintreeocc.filters;

import de.hybris.platform.commerceservices.enums.CustomerType;
import de.hybris.platform.commerceservices.order.CommerceCartService;
import de.hybris.platform.core.model.order.CartModel;
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.core.model.user.UserModel;
import de.hybris.platform.servicelayer.user.UserService;
import de.hybris.platform.site.BaseSiteService;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;

/**
 * This filter sets Customer into session using cartGuid.
 */
public class BraintreeGuestRoleFilter extends OncePerRequestFilter {

    private static final String CART_GUID = "cartGuid";

    private CommerceCartService commerceCartService;

    private BaseSiteService baseSiteService;

    private UserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                    FilterChain filterChain) throws ServletException, IOException {

        Optional.ofNullable(httpServletRequest.getParameter(CART_GUID)).ifPresent(cartGuid -> {
            CartModel cartModel = commerceCartService
                    .getCartForGuidAndSite(cartGuid, baseSiteService.getCurrentBaseSite());
            if (cartModel != null && userService.isAnonymousUser(userService.getCurrentUser())) {
                final UserModel um = cartModel.getUser();
                final CustomerModel cm = (CustomerModel) um;
                if (um != null && CustomerModel.class.isAssignableFrom(um.getClass()) && isGuest(cm)) {
                    userService.setCurrentUser(cm);
                }
            }
        });

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

    protected boolean isGuest(final CustomerModel cm) {
        if (cm == null || cm.getType() == null) {
            return false;
        }
        return cm.getType().toString().equals(CustomerType.GUEST.getCode());
    }

    public void setCommerceCartService(CommerceCartService commerceCartService) {
        this.commerceCartService = commerceCartService;
    }

    public void setBaseSiteService(BaseSiteService baseSiteService) {
        this.baseSiteService = baseSiteService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
