package executor

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

func computeResultMetadataID(columns []ColumnInfo) []byte {
	if len(columns) == 0 {
		return nil
	}
	hasher := sha256.New()
	var lenBuf [2]byte
	translator := NewQueryResultTranslator()
	for _, col := range columns {
		writeMetadataString(hasher, col.Keyspace, &lenBuf)
		writeMetadataString(hasher, col.Table, &lenBuf)
		writeMetadataString(hasher, col.Name, &lenBuf)
		typeInfoBytes := translator.writeTypeInfo(col.Type, col.TypeInfo)
		writeMetadataBytes(hasher, typeInfoBytes, &lenBuf)
	}
	return hasher.Sum(nil)
}

func writeMetadataString(hasher hash.Hash, value string, lenBuf *[2]byte) {
	binary.BigEndian.PutUint16(lenBuf[:], uint16(len(value)))
	_, _ = hasher.Write(lenBuf[:])
	if value != "" {
		_, _ = hasher.Write([]byte(value))
	}
}

func writeMetadataBytes(hasher hash.Hash, value []byte, lenBuf *[2]byte) {
	binary.BigEndian.PutUint16(lenBuf[:], uint16(len(value)))
	_, _ = hasher.Write(lenBuf[:])
	if len(value) > 0 {
		_, _ = hasher.Write(value)
	}
}
