package com.softwarebr.nunu.service.sms;

import com.brframework.commonweb.exception.HandleException;
import com.softwarebr.nunu.config.domain.ConfigService;
import com.softwarebr.nunu.domain.SMSConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * @author xu
 * @date 2019/10/29 11:41
 */
@Slf4j
public abstract class AbstractCaptchaService implements CaptchaService {
    @Autowired
    ConfigService<SMSConfig> smsConfigService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public void send(String phone, String business) {
        SMSConfig config = smsConfigService.get();

        String interval = redisTemplate.opsForValue().get(phone + business + "interval");
        if(StringUtils.isNotEmpty(interval)){
            throw new HandleException("发送过于频繁");
        }

        String captcha = (Math.random() + "").substring(2, config.getLength() + 2);
        sendCaptchaRequest(phone, business, captcha, config);


        //将验证码加到redis
        redisTemplate.opsForValue().set(phone + business, captcha, config.getTimeout(), TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(phone + business + "tautology", 0 + "", config.getTimeout(), TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(phone + business + "interval", "1", config.getInterval(), TimeUnit.SECONDS);
    }

    /**
     * 发送验证码请求
     * @param phone
     * @param business
     * @param captcha
     * @param config
     */
    protected abstract void sendCaptchaRequest(String phone, String business, String captcha, SMSConfig config);

    @Override
    public void verify(String phone, String business, String captcha) {
        SMSConfig config = smsConfigService.get();

        if(StringUtils.isNotEmpty(config.getGeneralCaptcha()) &&
                config.getGeneralCaptcha().equals(captcha)){
            log.info("用户{}使用通用验证码", phone);
            return;
        }

        String originalCaptcha = redisTemplate.opsForValue().get(phone + business);
        Long tautologyCount = redisTemplate.opsForValue().increment(phone + business + "tautology");
        if(tautologyCount == null || tautologyCount > config.getTautology()){
            throw new HandleException("验证码错误");
        }

        if(captcha.equals(originalCaptcha)){
            redisTemplate.delete(phone + business);
            redisTemplate.delete(phone + business + "tautology");
            return;
        }

        throw new HandleException("验证码错误");
    }
}
