// ui定制
package models

import (
	"errors"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/validation"
	"log"
	"sync"
	"fmt"
	"box-gm/utils"
	"github.com/garyburd/redigo/redis"
)

type BanIPInfo struct {
	IP		string	// 地址
}

type BanIPInfoArray []*BanIPInfo

var listBanIPInfo BanIPInfoArray
var bipfMutex sync.Mutex

func BanIPGetMajorKey() string {
	return "ban:ip"
}

func InitBanIPInfo() {
	pool := utils.GetAccountRedisPool()
	if pool == nil {
		fmt.Println("get redis pool fail")
		return
	}
	rd := pool.Get()
	defer rd.Close()
	if rd == nil {
		fmt.Println("get redis conn fail")
		return
	}
	key := BanIPGetMajorKey()
	result, _ := redis.Values(rd.Do("smembers", key))
	for _, v := range result {
		info := &BanIPInfo{
			IP: string(v.([]byte)),
		}
		listBanIPInfo = append(listBanIPInfo, info)
	}

	beego.Info("load ban ip info", len(listBanIPInfo))
}

func checkBanIPInfo(hf *BanIPInfo) (err error) {
	valid := validation.Validation{}
	b, _ := valid.Valid(&hf)
	if !b {
		for _, err := range valid.Errors {
			log.Println(err.Key, err.Message)
			return errors.New(err.Message)
		}
	}
	return nil
}

func AddBanIPInfo(hf *BanIPInfo) (error) {
	if err := checkBanIPInfo(hf); err != nil {
		return err
	}
	pool := utils.GetAccountRedisPool()
	if pool == nil {
		return errors.New("get redis conn fail")
	}
	rd := pool.Get()
	defer rd.Close()
	if rd == nil {
		return errors.New("get redis conn fail")
	}
	
	key := BanIPGetMajorKey()
	rd.Do("sadd", key, hf.IP)

	bipfMutex.Lock()
	listBanIPInfo = append(listBanIPInfo, hf)
	bipfMutex.Unlock()

	return nil
}

func DelBanIPInfoByIP(ip string) (error) {
	pool := utils.GetAccountRedisPool()
	if pool == nil {
		return errors.New("get redis conn fail")
	}
	rd := pool.Get()
	defer rd.Close()
	if rd == nil {
		return errors.New("get redis conn fail")
	}

	key := BanIPGetMajorKey()
	rd.Do("srem", key, ip)

	bipfMutex.Lock()
	defer bipfMutex.Unlock()
	for i := 0; i < len(listBanIPInfo); i++ {
		if ip == listBanIPInfo[i].IP {
			ii := i + 1
			listBanIPInfo = append(listBanIPInfo[:i], listBanIPInfo[ii:]...)
		}
	}

	return nil
}

func GetBanIPInfoByIP(ip string) (hf *BanIPInfo) {
	bipfMutex.Lock()
	defer bipfMutex.Unlock()

	for i := 0; i < len(listBanIPInfo); i++ {
		if ip == listBanIPInfo[i].IP {
			return listBanIPInfo[i]
		}
	}

	return nil
}

func GetBanIPInfo() BanIPInfoArray {
	bipfMutex.Lock()
	defer bipfMutex.Unlock()

	return listBanIPInfo
}
