package sdf

import (
	"crypto"
	"io"

	"golang.org/x/crypto/cryptobyte"
	"golang.org/x/crypto/cryptobyte/asn1"
	"xdx.jelly/xgcl/api/common"
)

func init() {
	panic("Use package xdx.jelly/xsxfv2 instead")
}

// PrivateKey implements the crypto.{Signer,Decrypter} interfaces
type PrivateKey struct {
	Sdfable
	Index   uint32
	KeyType KeyType

	publicKey interface{}
}

// ?
type PublicKey struct {
	Sdfable
	Index   uint32
	KeyType KeyType
}

// Public return the public key. 注意可能return nil
func (p *PrivateKey) Public() crypto.PublicKey {
	if p.publicKey != nil {
		return p
	}

	switch p.KeyType {
	case KeyTypeSm2Enc:
		if k, err := p.SDF_ExportEncPublicKey_ECC(p.Index); err != nil {
			return nil
		} else {
			p.publicKey = k
			return k
		}
	case KeyTypeSm2Sign:
		if k, err := p.SDF_ExportSignPublicKey_ECC(p.Index); err != nil {
			return nil
		} else {
			p.publicKey = k
			return k
		}
	default:
		return nil
	}
}

// Sign signs digest with the private key
// rand为nil，使用sdf接口的随机数. 有时rand也可以取如crypto/rand, 减少密码机调用，加快速度。
// SM2：digest输入预处理结果。opts输入nil
// RSA：TODO
// return: ASN1 encoded signature
func (p *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
	switch p.KeyType {
	case KeyTypeSm2Sign:
		sig, err := p.SDF_InternalSign_ECC(p.Index, digest)
		if err != nil {
			return nil, err
		}
		var b cryptobyte.Builder
		b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
			b.AddASN1BigInt(sig.R)
			b.AddASN1BigInt(sig.S)
		})
		return b.Bytes()
	default:
		return nil, common.SDR_NOTSUPPORT
	}
}

// Decrypter implements the crypto.Decryptor interface.
// rand为nil，使用sdf接口的随机数. 有时rand也可以取如crypto/rand, 减少密码机调用，加快速度。
// SM2：digest输入预处理结果。opts输入nil
// RSA：TODO
func (p *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) {
	switch p.KeyType {
	case KeyTypeSm2Enc:
		return nil, common.SDR_NOTSUPPORT

	default:
		return nil, common.SDR_NOTSUPPORT
	}
}
