package com.red.circle.auth.storage.impl;

import com.red.circle.auth.storage.RedCircleCredentialService;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.security.UserCredential;
import com.red.circle.tool.core.date.DateUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 凭证存储 实现.
 *
 * @author pengliang on 2023/4/28
 */
@Slf4j
@Service
public record RedCircleCredentialServiceImpl(
    RedisService redisService
) implements RedCircleCredentialService {


  @Override
  public UserCredential save(UserCredential userCredential) {
    long nowTime = DateUtils.now().getTime();
    if (userCredential.getExpireTime() <= nowTime) {
      throw new IllegalArgumentException("required [expireTime > nowTime]");
    }

    if (StringUtils.isBlank(userCredential.getSign())) {
      userCredential.setSign(userCredential.generateSign());
    }

    long expireTimeMilliseconds = userCredential.getExpireTime() - nowTime;
    redisService.setString(getAccessTokenCacheKey(userCredential.getUserId()),
        userCredential,
        expireTimeMilliseconds,
        TimeUnit.MILLISECONDS);
    log.info("save: userId={}", userCredential.getUserId());
    return userCredential;
  }

  @Override
  public boolean removeByUserId(Long userId) {
    log.info("removeByUserId: userId={}", userId);
    return redisService.delete(getAccessTokenCacheKey(userId));
  }

  @Override
  public UserCredential getByUserId(Long userId) {
    String val = redisService.getString(getAccessTokenCacheKey(userId));
    if (StringUtils.isBlank(val)) {
      return null;
    }
    return JacksonUtils.readValue(val, UserCredential.class);
  }

  @Override
  public UserCredential getByUserToken(String token) {
    String val = redisService.getString(getAccessTokenCacheKey(token));
    if (StringUtils.isBlank(val)) {
      return null;
    }
    return JacksonUtils.readValue(val, UserCredential.class);
  }

  @Override
  public boolean exists(Long userId) {
    return redisService.hash(getAccessTokenCacheKey(userId));
  }

}
