package cmb

import (
	"crypto/rand"
	"fmt"
	"math/big"
	"strings"
	"voucher/internal/pkg/helper"
)

func GenerateSM4Key() []byte {
	str := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
	buffer := make([]byte, 16)
	for i := 0; i < 16; i++ {
		nextInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(str))))
		buffer[i] = str[nextInt.Int64()]
	}
	return buffer
}

// GetSM4IV 获取SM4的IV
func GetSM4IV() []byte {
	return RandomBytes(16)
}

func RandomBytes(length int) []byte {
	str := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
	buffer := make([]byte, length)
	for i := 0; i < 16; i++ {
		nextInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(str))))
		buffer[i] = str[nextInt.Int64()]
	}
	return buffer
}

func Padding(input []byte, mode int) []byte {
	if input == nil {
		return nil
	} else {
		var ret []byte
		if mode == 1 {
			p := 16 - len(input)%16
			ret = make([]byte, len(input)+p)
			copy(ret, input)

			for i := 0; i < p; i++ {
				ret[len(input)+i] = byte(p)
			}
		} else {
			p := input[len(input)-1]
			ret = make([]byte, len(input)-int(p))
			copy(ret, input[:len(input)-int(p)])
		}

		return ret
	}
}

func AssemblingByteArray(key, iv []byte) []byte {
	os := make([]byte, 0)
	os = append(os, key...)
	os = append(os, []byte("|")...)
	os = append(os, iv...)
	return os
}

func SortStructStr(req interface{}) string {
	kvRows := helper.SortStructFieldsByKey(req)

	var strToBeSigned strings.Builder
	for _, kv := range kvRows {
		if kv.Key == "sign" {
			continue
		}
		if kv.Value == "" {
			continue
		}
		strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value))
	}

	return strings.TrimRight(strToBeSigned.String(), "&")
}
