package ctrlmessage

import (
	"crypto/ecdsa"
	"fmt"

	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
	frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
	frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
)

type SignedMessage interface {
	ReadSignedData([]byte) ([]byte, error)
	GetSignature() *control.Signature
	SetSignature(*control.Signature)
}

// Sign signs Control service ctrlmessage with private key.
func Sign(key *ecdsa.PrivateKey, msg SignedMessage) error {
	binBody, err := msg.ReadSignedData(nil)
	if err != nil {
		return fmt.Errorf("marshal request body: %w", err)
	}

	var sig frostfscrypto.Signature

	err = sig.Calculate(frostfsecdsa.Signer(*key), binBody)
	if err != nil {
		return fmt.Errorf("calculate signature: %w", err)
	}

	// TODO(@cthulhu-rider): #468 use Signature ctrlmessage from FrostFS API to avoid conversion
	var sigV2 refs.Signature
	sig.WriteToV2(&sigV2)

	var sigControl control.Signature
	sigControl.SetKey(sigV2.GetKey())
	sigControl.SetSign(sigV2.GetSign())

	msg.SetSignature(&sigControl)

	return nil
}