package entropy

import (
	"sync"

	"xdx.jelly/xgcl/grand/drng/entropy/rdtsc"
)

// SysTimeEntropySource 系统时间熵源
type SysTimeEntropySource struct {
	mu sync.Mutex
}

// GetEntropy
func (e *SysTimeEntropySource) GetEntropy(minEntropy int64, minEntropyInputLength int64, maxEntropyInputLength int64) ([]byte, error) {
	//使用互斥锁保证熵源的独占性
	e.mu.Lock()
	defer e.mu.Unlock()

	// SysTimeEntropySource熵源的Markov测试min entropy ~ 0.58
	// 因此向熵源最少要取minEntropy / 0.58 ~ 2*minEntropy
	n := minEntropy << 1
	if n < minEntropyInputLength {
		n = minEntropyInputLength
	}
	entropy := make([]byte, n)
	for i := int64(0); i < n; i++ {
		// var b byte
		// for j := 0; j < 8; j++ {
		// 	t := rdtsc.GetCPUTimeStamp()
		// 	// xor of the the last two bits are used.
		// 	// for a rdtsc usually used 20~50 cycles.
		// 	// b |= byte((t^(t>>1)^(t>>2)^(t>>3))&1) << j
		// 	b |= byte(t&1) << j
		// }
		// entropy[i] = b

		entropy[i] = byte(rdtsc.GetCPUTimeStamp())
	}
	return entropy, nil
}
