package com.red.circle.other.infra.database.cache.service.user.impl;

import com.red.circle.component.redis.service.RedisService;
import com.red.circle.other.infra.database.cache.key.user.UserKey;
import com.red.circle.other.infra.database.cache.service.user.UserRelationshipCacheService;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 用户关系缓存实现.
 *
 * @author pengliang on 2021/5/10
 */
@Service
@RequiredArgsConstructor
public class UserRelationshipCacheServiceImpl implements UserRelationshipCacheService {

  private final RedisService redisService;

  @Override
  public boolean checkFriend(Long userId, Long friendUserId,
      BiFunction<Long, Long, Boolean> orElseGetAndPut) {

    String key = getFriendRoomKey(userId, friendUserId);
    return Optional.ofNullable(redisService.getStringToBool(key))
        .map(val -> Objects.equals(val, Boolean.TRUE))
        .orElseGet(() -> {

          Boolean isFriend = Objects.equals(orElseGetAndPut.apply(userId, friendUserId),
              Boolean.TRUE);

          String reversalKey = getFriendRoomKey(userId,friendUserId);
          redisService.setString(key, isFriend, 1, TimeUnit.DAYS);
          redisService.setString(reversalKey, isFriend, 1, TimeUnit.DAYS);
          return isFriend;
        });
  }

  @Override
  public boolean checkFollow(Long userId, Long followUserId,
      BiFunction<Long, Long, Boolean> orElseGetAndPut) {

    String key = getFollowRoomKey(userId, followUserId);
    return Optional.ofNullable(redisService.getStringToBool(key))
        .map(val -> Objects.equals(val, Boolean.TRUE))
        .orElseGet(() -> {

          Boolean isFollow = Objects.equals(orElseGetAndPut.apply(userId, followUserId),
              Boolean.TRUE);

          redisService.setString(key, isFollow, 1, TimeUnit.DAYS);
          return isFollow;
        });
  }

  @Override
  public void removeFollowAll(Long userId, Long relationshipUid) {
    redisService.delete(Arrays.asList(
        getFollowRoomKey(userId, relationshipUid),
        getFollowRoomKey(relationshipUid, userId)
    ));
  }

  @Override
  public void removeFriend(Long userId, Long relationshipUid) {
    redisService.delete(List.of(
        getFriendRoomKey(userId, relationshipUid),
        getFriendRoomKey(relationshipUid, userId))
    );
  }

  private String getFriendRoomKey(Long userId, Long friendUserId) {
    return UserKey.CHECK_FRIEND.getKey(userId, friendUserId);
  }

  private String getFollowRoomKey(Long userId, Long friendUserId) {
    return UserKey.CHECK_FOLLOW.getKey(userId, friendUserId);
  }


}
