package workspace

import (
	"encoding/binary"
	"io"
)

// Length-prefix token encoder. Every field of every review fingerprint token
// flows through one of these helpers so the byte stream is unambiguous for
// any input — values containing newlines, spaces, NULs, or any other byte
// cannot be reinterpreted as a different field split.
//
// Format:
//   string: uint64 BE length (8 bytes) + raw UTF-8 bytes
//   int64:  uint64 BE (8 bytes, two's complement cast)
//   uint64: uint64 BE (8 bytes)
//   bool:   single byte (0 or 1)
//
// Every token also writes a length-prefixed domain tag as the FIRST field.
// The tag carries the token type and schema version, so two different token
// types cannot accidentally share the same byte stream even if their fields
// happen to line up. Bump the version suffix (e.g. .v1 → .v2) when a field
// is added, removed, or its encoding changes — that turns the change into a
// clean break instead of a silent collision.
//
// Do NOT mix these helpers with fmt.Fprintln/Fprintf in the same hash — fmt
// delimits with spaces and newlines, both of which are valid bytes inside a
// value, and the resulting stream is ambiguous (see the A/B collision case
// in TestBranchFileTokenInputsLengthPrefixIsAmbiguityFree).

const (
	branchFileTokenDomainV1          = "agentteam.review.branch-file.v1"
	workingFileTokenDomainV2         = "agentteam.review.working-file.v2"
	branchAggregateTokenDomainV1     = "agentteam.review.branch-aggregate.v1"
	workingAggregateTokenDomainV1    = "agentteam.review.working-aggregate.v1"
	repositoryTokenDomainV1          = "agentteam.review.repository.v1"
	branchSignatureFlightKeyDomainV1 = "agentteam.review.branch-signature-flight.v1"
	branchDiffFlightKeyDomainV1      = "agentteam.review.branch-diff-flight.v1"
)

func writeTokenString(h io.Writer, value string) {
	var lenBuf [8]byte
	binary.BigEndian.PutUint64(lenBuf[:], uint64(len(value)))
	_, _ = h.Write(lenBuf[:])
	_, _ = io.WriteString(h, value)
}

func writeTokenInt64(h io.Writer, value int64) {
	var buf [8]byte
	binary.BigEndian.PutUint64(buf[:], uint64(value))
	_, _ = h.Write(buf[:])
}

func writeTokenUint64(h io.Writer, value uint64) {
	var buf [8]byte
	binary.BigEndian.PutUint64(buf[:], value)
	_, _ = h.Write(buf[:])
}

func writeTokenBool(h io.Writer, value bool) {
	b := byte(0)
	if value {
		b = 1
	}
	_, _ = h.Write([]byte{b})
}
