package serviceconfiguration

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

func digestPrefixed(value []byte) string {
	digest := sha256.Sum256(value)
	return "sha256:" + hex.EncodeToString(digest[:])
}

func digestRaw(value []byte) string {
	digest := sha256.Sum256(value)
	return hex.EncodeToString(digest[:])
}

func canonicalPrefix(domain string) []byte {
	result := make([]byte, 0, len(domain)+1)
	result = append(result, domain...)
	return append(result, 0)
}

func appendCanonicalString(destination []byte, value string) []byte {
	return appendCanonicalBytes(destination, []byte(value))
}

func appendCanonicalBytes(destination, value []byte) []byte {
	destination = binary.BigEndian.AppendUint64(destination, uint64(len(value)))
	return append(destination, value...)
}

func appendCanonicalRevision(destination []byte, revision ExactOwnerRevision) []byte {
	destination = appendCanonicalString(destination, revision.RevisionID)
	return appendCanonicalString(destination, revision.ValueDigest)
}

func computeAccountRowID(generationID string, ordinal uint64, accountID string) string {
	preimage := canonicalPrefix("nexuscrm.connector-service-configuration-account-row/v1")
	preimage = appendCanonicalString(preimage, generationID)
	preimage = binary.BigEndian.AppendUint64(preimage, ordinal)
	preimage = appendCanonicalString(preimage, accountID)
	return digestRaw(preimage)
}

func computeBindingRowID(accountRowID string, catalogBindingOrdinal uint32) string {
	preimage := canonicalPrefix("nexuscrm.connector-service-configuration-binding-row/v1")
	preimage = appendCanonicalString(preimage, accountRowID)
	preimage = binary.BigEndian.AppendUint32(preimage, catalogBindingOrdinal)
	return digestRaw(preimage)
}

func computeCredentialSelectionRowID(
	bindingRowID string,
	ordinal uint64,
	credentialRef string,
) string {
	preimage := canonicalPrefix("nexuscrm.connector-service-configuration-credential-row/v1")
	preimage = appendCanonicalString(preimage, bindingRowID)
	preimage = binary.BigEndian.AppendUint64(preimage, ordinal)
	preimage = appendCanonicalString(preimage, credentialRef)
	return digestRaw(preimage)
}
