/**
* @Author: zou.yingbin
* @Create  : 2021/1/18 15:25
* @Modify  : 2021/1/18 15:25
 */

package mtpcache

import (
	"fmt"
	"mtp2_if/db"
	"mtp2_if/logger"
	"sync"
	"time"
)

var vGoodMgr middleGoodsMgr

// 套保商品缓存
type middleGoodsMgr struct {
	mtx  sync.RWMutex
	data map[uint32]MiddleGoods
	last time.Time
}

// 套保品种
type MiddleGoods struct {
	MIDDLEGOODSID    uint32  `json:"middlegoodsid"  xorm:"'MIDDLEGOODSID'"`       // 套保品种ID(SEQ_ERMS_MIDDLEGOODS)
	MIDDLEGOODSNAME  string  `json:"middlegoodsname"  xorm:"'MIDDLEGOODSNAME'"`   // 套保品种名称
	MIDDLEGOODSCODE  string  `json:"middlegoodscode"  xorm:"'MIDDLEGOODSCODE'"`   // 套保品种代码
	GOODSUNITID      int32   `json:"goodsunitid"  xorm:"'GOODSUNITID'"`           // 单位ID
	RELATEDGOODSID   int32   `json:"relatedgoodsid"  xorm:"'RELATEDGOODSID'"`     // 关联交易商品ID
	EVALUATERATIO    float64 `json:"evaluateratio"  xorm:"'EVALUATERATIO'"`       // 估价系数
	QTYDECIMALPLACE  int32   `json:"qtydecimalplace"  xorm:"'QTYDECIMALPLACE'"`   // 数量小数位
	RELATEDGOODSTYPE int32   `json:"relatedgoodstype"  xorm:"'RELATEDGOODSTYPE'"` // 关联商品类型 - 1:期货合约 2:现货品种
	NEEDHEDGERATIO   float64 `json:"needhedgeratio"  xorm:"'NEEDHEDGERATIO'"`     // 套保比率
	AREAUSERID       uint32  `json:"areauserid"  xorm:"'AREAUSERID'"`             // 机构用户ID
	GOODSGROUPID     int32   `json:"goodsgroupid"  xorm:"'GOODSGROUPID'"`         // 关联期货品种ID
	ISVALID          int32   `json:"isvalid"  xorm:"'ISVALID'"`                   // 状态 0-无效(停用) 1-有效(正常)
	MODIFYTIME       string  `json:"modifytime"  xorm:"'MODIFYTIME'"`             // 修改时间
}

func (r *middleGoodsMgr) isNeedLoad() bool {
	now := time.Now()
	// 间隔3秒以上重新加载
	if d := now.Sub(r.last); d.Seconds() >= 3 {
		return true
	}
	return false
}

// 加载数据
func (r *middleGoodsMgr) load() {
	r.mtx.Lock()
	defer r.mtx.Unlock()
	e := db.GetEngine()
	if e == nil {
		return
	}

	sqlId := "select MIDDLEGOODSID," +
		"       MIDDLEGOODSNAME," +
		"       MIDDLEGOODSCODE," +
		"       GOODSUNITID," +
		"       RELATEDGOODSID," +
		"       EVALUATERATIO," +
		"       QTYDECIMALPLACE," +
		"       RELATEDGOODSTYPE," +
		"       NEEDHEDGERATIO," +
		"       AREAUSERID," +
		"       GOODSGROUPID," +
		"       MODIFYTIME," +
		"       ISVALID" +
		"  from erms_middlegoods t"
	sData := make([]MiddleGoods, 0)
	s := e.SQL(sqlId)
	if err := s.Find(&sData); err == nil {
		r.data = make(map[uint32]MiddleGoods)
		for i := range sData {
			r.data[sData[i].MIDDLEGOODSID] = sData[i]
		}
		r.last = time.Now()
	} else {
		logger.GetLogger().Errorf("load middlegoods fail, %v", err)
	}
}

func (r *middleGoodsMgr) get(middleGoodsId uint32) (MiddleGoods, error) {
	r.mtx.RLock()
	defer r.mtx.RUnlock()
	if r.data == nil {
		return MiddleGoods{}, fmt.Errorf("not found")
	}

	if v, ok := r.data[middleGoodsId]; ok {
		return v, nil
	}

	return MiddleGoods{}, fmt.Errorf("not found")
}

func (r *middleGoodsMgr) getByUserID(userId uint32) ([]MiddleGoods, error) {
	r.mtx.RLock()
	defer r.mtx.RUnlock()
	ret := make([]MiddleGoods, 0)
	for _, v := range r.data {
		if v.AREAUSERID == userId {
			ret = append(ret, v)
		}
	}

	return ret, nil
}

// 获取套保商品
func GetMiddleGoods(middlGoodsId uint32) (MiddleGoods, error) {
	if v, err := vGoodMgr.get(middlGoodsId); err != nil {
		vGoodMgr.load()
	} else {
		return v, nil
	}

	return vGoodMgr.get(middlGoodsId)
}

// 获取指定用户套保商品
func GetMiddleGoodsByUserID(userId uint32) ([]MiddleGoods, error) {
	if vGoodMgr.isNeedLoad() {
		vGoodMgr.load()
	}
	return vGoodMgr.getByUserID(userId)
}

// 从数据库中获取套保商品
func GetMiddleGoodsFromDB(userId uint32) ([]MiddleGoods, error) {
	vGoodMgr.load()
	return vGoodMgr.getByUserID(userId)
}
