//go:build go1.19

package yu_rand

import (
	_ "unsafe"
)

//go:linkname Uint32 runtime.fastrand
//go:nosplit
func Uint32() uint32

//go:linkname Uint64 runtime.fastrand64
//go:nosplit
func Uint64() uint64

//go:linkname Uint runtime.fastrandu
//go:nosplit
func Uint() uint

// Int31
//
//	@Description: 返回一个非负伪随机 31 位整数
func Int31() int32 {
	return int32(Uint32() & (1<<31 - 1))
}

// Int63
//
//	@Description: 返回一个非负伪随机 63 位整数
func Int63() int64 {
	return int64(Uint64() & (1<<63 - 1))
}

// Uint31
//
//	@Description: 返回一个非负伪随机 31 位整数
func Uint31() uint32 {
	return Uint32() & (1<<31 - 1)
}

// Uint63
//
//	@Description: 返回一个非负伪随机 63 位整数
func Uint63() uint64 {
	return Uint64() & (1<<63 - 1)
}

// Int31n
//
//	@Description: 函数返回一个在[0,n)范围内的伪随机int32值。
func Int31n(n int32) int32 {
	if n <= 0 {
		panic("参数无效") // 如果n小于等于0，抛出异常
	}
	// if n&(n-1) == 0 { // 如果n是2的幂
	// 	return Int31() & (n - 1) // 返回一个随机数，并用n-1进行位与操作
	// }
	// j_max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) // 计算最大可能的随机数
	// j_v := Int31()                                    // 生成一个随机数
	// for j_v > j_max {
	// 	j_v = Int31() // 如果生成的随机数大于j_max，重新生成
	// }
	// return j_v % n // 返回随机数对n取余的结果
	return Int31() % n // 返回随机数对n取余的结果
}

// Int63n
//
//	@Description: 函数返回一个在[0,n)范围内的伪随机int64值。
func Int63n(n int64) int64 {
	if n <= 0 {
		panic("参数无效") // 如果n小于等于0，抛出异常
	}
	// if n&(n-1) == 0 { // 如果n是2的幂
	// 	return Int63() & (n - 1) // 返回一个随机数，并用n-1进行位与操作
	// }
	// j_max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) // 计算最大可能的随机数
	// j_v := Int63()                                    // 生成一个随机数
	// for j_v > j_max {
	// 	j_v = Int63() // 如果生成的随机数大于j_max，重新生成
	// }
	// return j_v % n // 返回随机数对n取余的结果
	return Int63() % n // 返回随机数对n取余的结果
}

// Uint31n
//
//	@Description: 函数返回一个在[0,n)范围内的伪随机int32值。
func Uint31n(n uint32) uint32 {
	if n <= 0 {
		panic("参数无效") // 如果n小于等于0，抛出异常
	}
	// if n&(n-1) == 0 { // 如果n是2的幂
	// 	return Int31() & (n - 1) // 返回一个随机数，并用n-1进行位与操作
	// }
	// j_max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) // 计算最大可能的随机数
	// j_v := Int31()                                    // 生成一个随机数
	// for j_v > j_max {
	// 	j_v = Int31() // 如果生成的随机数大于j_max，重新生成
	// }
	// return j_v % n // 返回随机数对n取余的结果
	return Uint31() % n // 返回随机数对n取余的结果
}

// Uint63n
//
//	@Description: 函数返回一个在[0,n)范围内的伪随机int64值。
func Uint63n(n uint64) uint64 {
	if n <= 0 {
		panic("参数无效") // 如果n小于等于0，抛出异常
	}
	// if n&(n-1) == 0 { // 如果n是2的幂
	// 	return Int63() & (n - 1) // 返回一个随机数，并用n-1进行位与操作
	// }
	// j_max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) // 计算最大可能的随机数
	// j_v := Int63()                                    // 生成一个随机数
	// for j_v > j_max {
	// 	j_v = Int63() // 如果生成的随机数大于j_max，重新生成
	// }
	// return j_v % n // 返回随机数对n取余的结果
	return Uint63() % n // 返回随机数对n取余的结果
}

// Int31MinMax
//
//	@Description: 函数返回一个在[min, max]范围内的随机整数。如果min大于max，函数会抛出一个panic。
func Int31MinMax(min, max int32) int32 {
	if min > max {
		panic("min必须小于或等于max")
	}
	return min + Int31n(max-min+1)
}

// Int63MinMax
//
//	@Description: 函数返回一个在[min, max]范围内的随机整数。如果min大于max，函数会抛出一个panic。
func Int63MinMax(min, max int64) int64 {
	if min > max {
		panic("min必须小于或等于max")
	}
	return min + Int63n(max-min+1)
}

// Uint31MinMax
//
//	@Description: 函数返回一个在[min, max]范围内的随机整数。如果min大于max，函数会抛出一个panic。
func Uint31MinMax(min, max uint32) uint32 {
	if min > max {
		panic("min必须小于或等于max")
	}
	return min + Uint31n(max-min+1)
}

// Uint63MinMax
//
//	@Description: 函数返回一个在[min, max]范围内的随机整数。如果min大于max，函数会抛出一个panic。
func Uint63MinMax(min, max uint64) uint64 {
	if min > max {
		panic("min必须小于或等于max")
	}
	return min + Uint63n(max-min+1)
}

// IntMinMax
//
//	@Description: 函数返回一个在[min, max]范围内的随机整数。如果min大于max，函数会抛出一个panic。
func IntMinMax(min, max int) int {
	if min > max {
		panic("min必须小于或等于max")
	}
	return min + Intn(max-min+1)
}

type rand struct{}

func (r rand) Read(p []byte) (n int, err error) {
	for j_i := 0; j_i < len(p); j_i++ {
		p[j_i] = byte(Uint32())
	}
	return len(p), nil
}

func (r rand) ReadEx(p []byte, ex []byte) (n int, err error) {
	for j_i := 0; j_i < len(p); j_i++ {
		p[j_i] = ex[Intn(len(ex))]
	}
	return len(p), nil
}

var Rand rand
