package review

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

// reviewContextTargetHash is the deterministic dedup key for a review target:
// full sha256 hex over the NUL-separated target tuple. Do not case-fold
// (remote machines may be case-sensitive). Empty base/head participate as
// empty so the same input always maps to one key.
//
// RootPath is the canonical filesystem path and is hashed RAW — NOT trimmed.
// Two worktrees whose canonical roots differ only by trailing whitespace
// ("/repo" vs "/repo ") are distinct targets and MUST get distinct hashes;
// trimming would silently collapse them into one row on the next upsert.
// machineID and the refs are control strings (IDs / git refs), so their
// trim-normalization is the established enum/ref discipline and is retained.
func reviewContextTargetHash(machineID, rootPath, baseRef, headRef string) string {
	h := sha256.Sum256([]byte(strings.Join([]string{
		strings.TrimSpace(machineID), rootPath,
		strings.TrimSpace(baseRef), strings.TrimSpace(headRef),
	}, "\x00")))
	return hex.EncodeToString(h[:])
}

func reviewContextTaskTargetHash(taskScopeID, machineID, rootPath, baseRef, headRef string) string {
	h := sha256.Sum256([]byte(strings.Join([]string{
		"task", strings.TrimSpace(taskScopeID), strings.TrimSpace(machineID), rootPath,
		strings.TrimSpace(baseRef), strings.TrimSpace(headRef),
	}, "\x00")))
	return hex.EncodeToString(h[:])
}

func reviewContextTargetHashForScope(taskScopeID, machineID, rootPath, baseRef, headRef string) string {
	if strings.TrimSpace(taskScopeID) != "" {
		return reviewContextTaskTargetHash(taskScopeID, machineID, rootPath, baseRef, headRef)
	}
	return reviewContextTargetHash(machineID, rootPath, baseRef, headRef)
}
