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

import com.google.common.collect.Lists;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.infra.database.cache.key.user.RequestBlacklistKey;
import com.red.circle.other.infra.database.cache.service.user.RequestBlacklistService;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * @author pengliang on 2022/3/22
 */
@Service
@RequiredArgsConstructor
public class RequestBlacklistServiceImpl implements RequestBlacklistService {

  private final RedisService redisService;

  @Override
  public void addIp(String ip) {
    if (StringUtils.isBlank(ip)) {
      return;
    }
    String newIp = ip.trim();
    redisService.hashPut(getRootKey(),
        getIpKey(newIp),
        newIp);
  }

  private String getIpKey(String ip) {
    return RequestBlacklistKey.IP.getKey(ip);
  }

  @Override
  public void addPhoneModel(String phoneModel) {
    if (StringUtils.isBlank(phoneModel)) {
      return;
    }
    String newPhoneModel = phoneModel.trim();
    redisService.hashPut(getRootKey(),
        getPhoneModelKey(newPhoneModel),
        newPhoneModel);
  }

  @Override
  public void delKey(String key) {
    redisService.hashDelete(getRootKey(), key);
  }

  private String getRootKey() {
    return RequestBlacklistKey.REQUEST_BLACK.getKey();
  }

  private String getPhoneModelKey(String phoneModel) {
    return RequestBlacklistKey.PHONE_MODEL.getKey(phoneModel.toUpperCase());
  }

  @Override
  public boolean matchIpOrPhoneModel(String ip, String phoneModel) {
    List<String> keys = getIpKeys(ip);
    keys.add(getPhoneModelKey(phoneModel));
    List<String> results = redisService.hashMultiGetToString(getRootKey(), keys);
    if (CollectionUtils.isEmpty(results)) {
      return false;
    }

    for (String result : results) {
      if (Objects.equals(result, "null")) {
        continue;
      }
      if (StringUtils.isNotBlank(result)) {
        return true;
      }
    }
    return false;
  }

  @Override
  public Set<String> getKeys() {
    return redisService.hashKeys(getRootKey());
  }

  private List<String> getIpKeys(String ip) {
    if (StringUtils.isBlank(ip)) {
      return Lists.newArrayList();
    }
    String[] ipParagraph = ip.split("\\.");
    List<String> ips = Lists.newArrayList();
    ips.add(getIpKey(ip));
    int ipLen = ipParagraph.length;
    String newIp = ip;
    for (int index = 0; index < ipLen - 1; index++) {
      newIp = newIp.substring(0, newIp.lastIndexOf("."));
      ips.add(getIpKey(newIp));
    }
    return ips;
  }

}
