package models

import (
	"fmt"
	"strconv"
	"sync"
	"time"
)

// 主要用于Oracle ID生成，具有原子操作性质
var lock sync.Mutex

var requestMap = map[string]int{}

// GetSerialNumber 获取SerialNumber，用于Oracle业务类ID主键生成，有原子操作性质
func GetSerialNumber(prefix string) (int64, error) {
	lock.Lock()

	str := ""
	timeStamp := time.Now().Unix()

	if current, ok := requestMap[prefix]; ok {
		curStr := repZero(current, 6)
		str = fmt.Sprintf("%s%d%s", prefix, timeStamp, curStr)
		current++
		requestMap[prefix] = current
	} else {
		current = 1
		curStr := repZero(current, 6)
		str = fmt.Sprintf("%s%d%s", prefix, timeStamp, curStr)
		current++
		requestMap[prefix] = current
	}

	defer lock.Unlock()
	return strconv.ParseInt(str, 10, 64)
}

//  repZero 按位数补零
func repZero(number, digit int) string {
	str := strconv.Itoa(number)
	len := len(str)
	if len >= digit {
		return str
	}

	need := digit - len
	for i := 0; i < need; i++ {
		str = "0" + str
	}

	return str
}
