package crypto

import (
	"agent/defines/dcrypto/dcipher"
	"agent/defines/derrs"
	"agent/internal/include"
)

type ICipher interface {
	New(key any) ICipher

	Encrypt(input []byte, output []byte) (size int, err error)
	Decrypt(input []byte, output []byte) (size int, err error)

	EncryptOutputSize(inputSize int) int
	DecryptOutputSize(inputSize int) int

	BlockSize() int
}

var ciphers = map[string]func(key any) (ICipher, error){
	dcipher.TagAesCtr: NewAesCtr,
	dcipher.TagRc4:    NewRc4,
	dcipher.TagXor:    NewXorCipher,
	dcipher.TagXor4:   NewXorCipher,
	dcipher.TagXor8:   NewXorCipher,
	dcipher.TagXor16:  NewXorCipher,
	dcipher.TagXor32:  NewXorCipher,
}

func NewCipher(client include.IClient) (ICipher, error) {
	if client == nil {
		return nil, derrs.NewIncorrectParamsError("client is nil")
	}
	clientCfg := &client.Config().Client
	newCipher := ciphers[clientCfg.Cipher.Name]
	if newCipher == nil {
		return nil, derrs.NewIncorrectParamsError("unsupported cipher name")
	}
	return newCipher(clientCfg.Cipher.Key)
}
