package sagan.team.support;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import sagan.search.support.SearchService;
import sagan.team.MemberProfile;

import java.util.List;

/**
 * Service providing high-level, selectively cached data access and other
 * {@link MemberProfile}-related operations.
 */
@Service
public class TeamService {

    private static Log logger = LogFactory.getLog(TeamService.class);

    public static final String CACHE_NAME = "cache.team";
    public static final Class CACHE_TYPE = MemberProfile.class;
    public static final String CACHE_TTL = "${cache.team.timetolive:60}";

    private final TeamRepository teamRepository;
    private final SearchService searchService;
    private final MemberProfileSearchEntryMapper mapper;

    @Autowired
    public TeamService(TeamRepository teamRepository, SearchService searchService,
                       MemberProfileSearchEntryMapper mapper) {
        this.teamRepository = teamRepository;
        this.searchService = searchService;
        this.mapper = mapper;
    }

    public MemberProfile fetchMemberProfile(Long id) {
        return teamRepository.findById(id);
    }

    @Cacheable(CACHE_NAME)
    public MemberProfile fetchMemberProfileUsername(String username) {
        MemberProfile profile = teamRepository.findByUsername(username);
        if (profile == null) {
            profile = MemberProfile.NOT_FOUND;
        }
        return profile;
    }

    public void updateMemberProfile(Long id, MemberProfile profile) {
        updateMemberProfile(profile, fetchMemberProfile(id));
    }

    @CacheEvict(value = CACHE_NAME, key = "#username")
    public void updateMemberProfile(String username, MemberProfile updatedProfile) {
        updateMemberProfile(updatedProfile, fetchMemberProfileUsername(username));
    }

    private void updateMemberProfile(MemberProfile profile, MemberProfile existingProfile) {
        existingProfile.setSpeakerdeckUsername(profile.getSpeakerdeckUsername());
        existingProfile.setTwitterUsername(profile.getTwitterUsername());
        existingProfile.setBio(profile.getBio());
        existingProfile.setName(profile.getName());
        existingProfile.setJobTitle(profile.getJobTitle());
        existingProfile.setTwitterUsername(profile.getTwitterUsername());
        existingProfile.setSpeakerdeckUsername(profile.getSpeakerdeckUsername());
        existingProfile.setLanyrdUsername(profile.getLanyrdUsername());
        existingProfile.setGplusId(profile.getGplusId());
        existingProfile.setLocation(profile.getLocation());
        existingProfile.setGeoLocation(profile.getGeoLocation());
        existingProfile.setVideoEmbeds(profile.getVideoEmbeds());
        existingProfile.setGravatarEmail(profile.getGravatarEmail());
        existingProfile.setHidden(profile.isHidden());

        if (!StringUtils.isEmpty(profile.getGravatarEmail())) {
            Md5PasswordEncoder encoder = new Md5PasswordEncoder();
            String hashedEmail = encoder.encodePassword(profile.getGravatarEmail(), null);
            existingProfile.setAvatarUrl(String.format("http://gravatar.com/avatar/%s", hashedEmail));
        }

        teamRepository.save(existingProfile);
        try {
            searchService.saveToIndex(mapper.map(existingProfile));
        } catch (Exception e) {
            logger.warn("Indexing failed for " + existingProfile.getId(), e);
        }
    }

    public List<MemberProfile> fetchActiveMembers() {
        return teamRepository.findByHiddenOrderByNameAsc(false);
    }

    public List<MemberProfile> fetchHiddenMembers() {
        return teamRepository.findByHiddenOrderByNameAsc(true);
    }

    public MemberProfile createOrUpdateMemberProfile(Long githubId, String username, String avatarUrl, String name) {
        MemberProfile profile = teamRepository.findByGithubId(githubId);

        if (profile == null) {
            profile = new MemberProfile();
            profile.setGithubId(githubId);
            profile.setUsername(username);
            profile.setHidden(true);
        }
        profile.setAvatarUrl(avatarUrl);
        profile.setName(name);
        profile.setGithubUsername(username);
        return teamRepository.save(profile);
    }

    public void showOnlyTeamMembersWithIds(List<Long> userIds) {
        teamRepository.hideTeamMembersNotInIds(userIds);
    }
}

@@ -3208,25 +3208,24 @@
 den());%0A
-%0A
         
 if (!Str
@@ -3220,334 +3220,53 @@
     
-if (!StringUtils.isEmpty(profile.getGravatarEmail())) %7B%0A            Md5PasswordEncoder encoder = new Md5PasswordEncoder();%0A            String hashedEmail = encoder.encodePassword(profile.getGravatarEmail(), null);%0A            existingProfile.setAvatarUrl(String.format(%22http://gravatar.com/avatar/%25s%22, hashedEmail));%0A        %7D
+updateAvatarUrlwithGravatar(existingProfile);
 %0A%0A  
@@ -4277,32 +4277,78 @@
 name(username);%0A
+        updateAvatarUrlwithGravatar(profile);%0A
         return t
@@ -4510,11 +4510,415 @@
 );%0A    %7D
+%0A%0A    private void updateAvatarUrlwithGravatar(MemberProfile profile) %7B%0A        if (!StringUtils.isEmpty(profile.getGravatarEmail())) %7B%0A            Md5PasswordEncoder encoder = new Md5PasswordEncoder();%0A            String hashedEmail = encoder.encodePassword(profile.getGravatarEmail(), null);%0A            profile.setAvatarUrl(String.format(%22http://gravatar.com/avatar/%25s%22, hashedEmail));%0A        %7D%0A    %7D
 %0A%7D%0A

Fix avatar URL issues in team page