package filterPoly

import (
	"app.yhyue.com/moapp/jybase/common"
	"app.yhyue.com/moapp/jybase/mongodb"
	log "app.yhyue.com/moapp/jylog"
	"bp.jydev.jianyu360.cn/BaseService/gateway/common/db"
	"fmt"
	"github.com/gogf/gf/v2/util/gconv"
	"strings"
	"time"
)

// syncBlackWhiteList 同步永久黑名单白名单
func syncBlackWhiteList() {
	mgSess := db.MgoJy.GetMgoConn()
	defer func() {
		db.MgoJy.DestoryMongoConn(mgSess)
	}()
	log.Info("开始同步黑白名单")
	addBlackNum, addWhiteNum := 0, 0
	// 从用户表同步黑名单
	iter := mgSess.DB("qfw").C("user").Find(map[string]interface{}{"i_ban": 1}).Select(map[string]interface{}{"_id": 1}).Iter()
	uData := map[string]interface{}{}
	for iter.Next(&uData) {
		uid := mongodb.BsonIdToSId(uData["_id"])
		blackKey := fmt.Sprintf(BlackListKey, uid)
		if !AllRedis.Exists(blackKey) {
			AllRedis.Set(blackKey, 1, -1)
			log.Infof("同步黑名单-加入%s", uid)
			addBlackNum++
		}
	}

	// 从黑名单白名单列表同步
	res := db.GateWatMySql.Query(`SELECT * FROM front_proxy_blackWhite Where status !=0`)
	if res != nil && len(*res) > 0 {
		for _, data := range *res {
			value := gconv.String(data["value"])
			status := gconv.Int(data["status"])
			if key := fmt.Sprintf(WhiteListKey, value); status == 1 && !AllRedis.Exists(key) {
				addWhiteNum++
				AllRedis.Set(key, 1, -1)
				log.Info("同步白名单-加入%s", value)
			} else if key := fmt.Sprintf(BlackListKey, value); status == -1 && !AllRedis.Exists(key) {
				addBlackNum++
				AllRedis.Set(key, 1, -1)
				log.Info("同步黑名单-加入%s", value)
			}
		}
	}

	log.Info("同步结束,共新增%d个黑名单,%d个白名单", addBlackNum, addWhiteNum)
}

// checkBackList 查询是否在白名单中
func (a *ReqFilterPoly) checkWhiteList(k string) bool {
	return AllRedis.Get(fmt.Sprintf(WhiteListKey, k)) != nil
}

// checkBackList 查询是否在黑名单中
func (a *ReqFilterPoly) checkBackList(k string) bool {
	return AllRedis.Get(fmt.Sprintf(BlackListKey, k)) != nil
}

// addBackList 加入黑名单
func (a *ReqFilterPoly) addBackList(k, cause string) {
	timeLong := a.Rule.TempBlockTime
	blockTimes := a.Rule.IdMaxBlockTimes
	isIp := strings.Index(k, ".") > -1
	if isIp {
		blockTimes = a.Rule.IpMaxBlockTimes
	}
	//统计临时黑名单次数,超过次数进入永久黑名单
	if !RateOk(fmt.Sprintf(BlackTimesKey, k), blockTimes[1], time.Duration(blockTimes[0])*time.Second) {
		log.Infof("%s 多次进入临时黑名单，现转移至永久黑名单", k)
		timeLong = -1
	}
	AllRedis.Set(fmt.Sprintf(BlackListKey, k), 1, timeLong)
	go func() {
		//保存黑名单记录
		db.MgoJy.Save("anti_black", map[string]interface{}{
			"s_userid":    common.If(isIp, "", k),
			"s_ip":        common.If(isIp, k, ""),
			"l_comeTime":  time.Now().Unix(),
			"l_blackLong": timeLong,
			"s_platform":  "gateway",
			"s_alias":     a.Rule.Alias,
			"s_cause":     cause,
		})
		if !isIp && timeLong == -1 {
			db.MgoJy.UpdateById("user", k, map[string]interface{}{"$set": map[string]interface{}{"i_ban": 1}})
		}
	}()
}
