package org.xcolab.view.auth;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.util.WebUtils;

import org.xcolab.client.members.MembersClient;
import org.xcolab.client.members.PermissionsClient;
import org.xcolab.client.members.exceptions.MemberNotFoundException;
import org.xcolab.client.members.exceptions.UncheckedMemberNotFoundException;
import org.xcolab.client.members.pojo.Member;
import org.xcolab.view.auth.login.spring.MemberDetails;

import java.util.Objects;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

public class AuthenticationContext {

    public static final String IMPERSONATE_MEMBER_ID_COOKIE_NAME = "X-Impersonate-userId";

    public boolean isLoggedIn() {
        return getRealMemberOrNull() != null;
    }

    public boolean isImpersonating(HttpServletRequest request) {
        return !Objects.equals(getMemberOrNull(request), getRealMemberOrNull());
    }

    public Member getMemberOrNull(HttpServletRequest request) {
        final Member realMemberOrNull = getRealMemberOrNull();
        if (PermissionsClient.canAdminAll(realMemberOrNull)) {
            Long impersonateduserId = getImpersonateduserId(request);
            if (impersonateduserId != null) {
                try {
                    return MembersClient.getMember(impersonateduserId);
                } catch (MemberNotFoundException e) {
                    return realMemberOrNull;
                }
            }
        }
        return realMemberOrNull;
    }

    private static Long getImpersonateduserId(HttpServletRequest request) {
        final Cookie cookie = WebUtils.getCookie(request, IMPERSONATE_MEMBER_ID_COOKIE_NAME);

        Long impersonateduserId = null;
        if (cookie != null && StringUtils.isNumeric(cookie.getValue())) {
            impersonateduserId = Long.parseLong(cookie.getValue());
        }
        return impersonateduserId;
    }

    public Member getRealMemberOrNull() {
        final Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        return getRealMemberOrNull(authentication);
    }

    public Member getRealMemberOrNull(Authentication authentication) {
        if (authentication != null && authentication.isAuthenticated()
                && authentication.getPrincipal() instanceof MemberDetails) {
            MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal();
            return memberDetails.getMember();
        } else {
            return null;
        }
    }

    public Member getMemberOrThrow(HttpServletRequest request) {
        Member member = getMemberOrNull(request);
        if (member != null) {
            return member;
        }

        throw new UncheckedMemberNotFoundException("No member logged in - check before calling");
    }
}

@@ -1842,33 +1842,33 @@
 ong impersonated
-u
+U
 serId = null;%0A  
@@ -1955,33 +1955,33 @@
     impersonated
-u
+U
 serId = Long.par
@@ -2040,25 +2040,25 @@
 impersonated
-u
+U
 serId;%0A    %7D

Rename variable