package sm2

import (
	"math/big"

	"xdx.jelly/xgcl/gmath"

	"xdx.jelly/xgcl/api/common"
)

// MarshalSDF export privateKey to SDF type.
func (privateKey *PrivateKey) MarshalSDF(sdfPrivateKey *common.ECCrefPrivateKey) error {
	sdfPrivateKey.Bits = uint32(byteSize * 8)
	if privateKey.D.BitLen() > byteSize*8 {
		return common.SDR_KEYERR
	}
	_ = gmath.FillBytes(privateKey.D, sdfPrivateKey.K[:])
	return nil
}

// UnmarshalSDF import privateKey from SDF type.
func (privateKey *PrivateKey) UnmarshalSDF(sdfPrivateKey *common.ECCrefPrivateKey) error {
	if privateKey.D == nil {
		privateKey.D = new(big.Int)
	}
	privateKey.D.SetBytes(sdfPrivateKey.K[:])
	px, py := Curve().ScalarBaseMult(privateKey.D.Bytes())
	privateKey.PublicKey = PublicKey{Curve: Curve(), X: px, Y: py}
	return nil
}

// MarshalSDF export publicKey to SDF type.
func (publicKey *PublicKey) MarshalSDF(sdfPublicKey *common.ECCrefPublicKey) error {
	sdfPublicKey.Bits = uint32(byteSize * 8)
	if publicKey.X.BitLen() > byteSize*8 || publicKey.Y.BitLen() > byteSize*8 {
		return common.SDR_UNKNOWERR
	}

	_ = gmath.FillBytes(publicKey.X, sdfPublicKey.X[:])
	_ = gmath.FillBytes(publicKey.Y, sdfPublicKey.Y[:])

	return nil
}

// UnmarshalSDF import publicKey from SDF type.
func (publicKey *PublicKey) UnmarshalSDF(sdfPublicKey *common.ECCrefPublicKey) error {
	publicKey.X.SetBytes(sdfPublicKey.X[:])
	publicKey.Y.SetBytes(sdfPublicKey.Y[:])
	return nil
}

// MarshalSDF export privateKey to SDF type.
func (signature *Signature) MarshalSDF(sdfSignature *common.ECCSignature) error {

	if signature.R.BitLen() > byteSize*8 || signature.S.BitLen() > byteSize*8 {
		return common.SDR_UNKNOWERR
	}
	_ = gmath.FillBytes(signature.R, sdfSignature.R[:])
	_ = gmath.FillBytes(signature.S, sdfSignature.S[:])
	return nil
}

// UnmarshalSDF import signature from SDF type.
func (signature *Signature) UnmarshalSDF(sdfSignature *common.ECCSignature) error {
	signature.R.SetBytes(sdfSignature.R[:])
	signature.S.SetBytes(sdfSignature.S[:])
	return nil
}

// MarshalSDF export signature to SDF type.
func (cipher *Cipher) MarshalSDF(sdfCipher *common.ECCCipher) error {
	if cipher.X.BitLen() > byteSize*8 || cipher.Y.BitLen() > byteSize*8 {
		return common.SDR_UNKNOWERR
	}

	_ = gmath.FillBytes(cipher.X, sdfCipher.X[:])
	_ = gmath.FillBytes(cipher.Y, sdfCipher.Y[:])
	sdfCipher.M = cipher.Hash
	sdfCipher.L = uint32(len(cipher.C))
	sdfCipher.C = append(sdfCipher.C[:0], cipher.C...)
	return nil
}

// UnmarshalSDF import privateKey from SDF type.
func (cipher *Cipher) UnmarshalSDF(sdfCipher *common.ECCCipher) error {

	cipher.X.SetBytes(sdfCipher.X[:])
	cipher.Y.SetBytes(sdfCipher.Y[:])
	cipher.Hash = sdfCipher.M
	cipher.C = append(cipher.C[:0], sdfCipher.C...)
	return nil
}
