package flowcommandv3

import (
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"encoding/hex"
)

// ComputeInputDigest binds the exact canonical Flow inputs and explicit
// external-effects mode using the frozen v3 cross-language grammar:
//
//   - ASCII domain prefix "nexuscrm-runtime-flow-command-input-v3";
//   - mode and canonical inputs in that order;
//   - every value encoded as unsigned-varint length plus exact bytes.
func ComputeInputDigest(canonicalInputs []byte, mode ExternalEffectsMode) (string, error) {
	if !mode.Valid() || !validCanonicalInputs(canonicalInputs) {
		return "", invalidPayload()
	}
	var out bytes.Buffer
	writeBytes(&out, []byte("nexuscrm-runtime-flow-command-input-v3"))
	writeBytes(&out, []byte(mode))
	writeBytes(&out, canonicalInputs)
	digest := sha256.Sum256(out.Bytes())
	return "sha256:" + hex.EncodeToString(digest[:]), nil
}

func writeBytes(out *bytes.Buffer, value []byte) {
	var encoded [binary.MaxVarintLen64]byte
	n := binary.PutUvarint(encoded[:], uint64(len(value)))
	out.Write(encoded[:n])
	out.Write(value)
}
