package no.uio.ifi.trackfind.backend.security;

import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import no.uio.ifi.trackfind.backend.pojo.TfUser;
import no.uio.ifi.trackfind.backend.repositories.UserRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Map;

@Slf4j
@Service
public class TrackFindUserDetailsService implements UserDetailsService {

    @Value("${trackfind.admin}")
    private String adminElixirId;

    private UserRepository userRepository;

    // Note that username is not really a username here, it's a JSON serialized map of OIDC parameters
    @SuppressWarnings("unchecked")
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Map<String, String> userDetails = new Gson().fromJson(username, Map.class);
        String elixirId = userDetails.get("oidc_claim_sub");
        if (StringUtils.isEmpty(elixirId)) {
            return new User("Anonymous", "Anonymous", false, false, false, false, AuthorityUtils.NO_AUTHORITIES);
        }
        TfUser user = userRepository.findByElixirId(elixirId);
        if (user == null) {
            user = userRepository.save(generateNewUser(userDetails, elixirId));
            log.info("New user saved: {}", user);
        }
        return user;
    }

    /**
     * Gets all users.
     *
     * @return All users.
     */
    public Collection<TfUser> getAllUsers() {
        return userRepository.findAll();
    }

    /**
     * Activates user.
     *
     * @param user User to be activated.
     */
    public void activateUser(TfUser user) {
        user.setActive(true);
        userRepository.save(user);
    }

    /**
     * Deactivates user.
     *
     * @param user User to be deactivated.
     */
    public void deactivateUser(TfUser user) {
        user.setActive(false);
        userRepository.save(user);
    }

    /**
     * Grants a user with ADMIN authority.
     *
     * @param user Target user.
     */
    public void grantAdminAuthority(TfUser user) {
        user.setAdmin(true);
        userRepository.save(user);
    }

    /**
     * Revokes ADMIN authority from the user.
     *
     * @param user Target user.
     */
    public void revokeAdminAuthority(TfUser user) {
        user.setAdmin(false);
        userRepository.save(user);
    }

    private TfUser generateNewUser(Map<String, String> userDetails, String elixirId) {
        return new TfUser(
                null,
                elixirId,
                userDetails.get("oidc_claim_preferred_username"),
                userDetails.get("oidc_claim_name"),
                userDetails.get("oidc_claim_email"),
                adminElixirId.equalsIgnoreCase(elixirId),
                true,
                null
        );
    }

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

}

@@ -1435,63 +1435,28 @@
     
-if (StringUtils.isEmpty(elixirId)) %7B%0A            return
+User anonymousUser =
  new
@@ -1547,16 +1547,95 @@
 ITIES);%0A
+        if (StringUtils.isEmpty(elixirId)) %7B%0A            return anonymousUser;%0A
         
@@ -1723,16 +1723,52 @@
  == null
+ && StringUtils.isNotEmpty(username)
 ) %7B%0A    
@@ -1779,35 +1779,31 @@
     
-u
+TfU
 ser 
-= userRepository.save(
+generatedUser = 
 gene
@@ -1836,19 +1836,135 @@
 lixirId)
-)
 ;%0A
+            if (generatedUser.getUsername() != null) %7B%0A                user = userRepository.save(generatedUser);%0A   
         
@@ -1967,16 +1967,17 @@
         
+ 
 log.info
@@ -2002,24 +2002,97 @@
 %7B%7D%22, user);%0A
+            %7D else %7B%0A                return anonymousUser;%0A            %7D%0A
         %7D%0A  

Fix logs polluting by TrackFindUserDetailsService