// Package updater handles binary self-update with Ed25519 signature verification.
// See bible/rules/patterns/release-signing/contract.md for the full contract.
package updater

import (
	"crypto/ed25519"
	"encoding/base64"
	"fmt"
	"strings"
)

// trustedKeysRaw is injected at release build time via:
//
//	-ldflags "-X bee/audit/internal/updater.trustedKeysRaw=base64key1:base64key2"
//
// Empty in dev builds — updates are disabled when empty.
var trustedKeysRaw string

// TrustedKeys decodes the embedded public keys.
// Returns an error if the binary was built without key injection (dev build).
func TrustedKeys() ([]ed25519.PublicKey, error) {
	if strings.TrimSpace(trustedKeysRaw) == "" {
		return nil, fmt.Errorf("dev build: trusted keys not embedded, updates disabled")
	}
	var keys []ed25519.PublicKey
	for _, enc := range strings.Split(trustedKeysRaw, ":") {
		enc = strings.TrimSpace(enc)
		if enc == "" {
			continue
		}
		b, err := base64.StdEncoding.DecodeString(enc)
		if err != nil {
			return nil, fmt.Errorf("decode trusted key: %w", err)
		}
		if len(b) != ed25519.PublicKeySize {
			return nil, fmt.Errorf("trusted key has wrong size: got %d, want %d", len(b), ed25519.PublicKeySize)
		}
		keys = append(keys, ed25519.PublicKey(b))
	}
	if len(keys) == 0 {
		return nil, fmt.Errorf("no valid trusted keys found in build")
	}
	return keys, nil
}

// VerifySignature returns nil if sig was produced by any trusted key over data.
// Returns an error (never panics) on any failure — caller logs and continues.
func VerifySignature(data, sig []byte) error {
	keys, err := TrustedKeys()
	if err != nil {
		return err
	}
	for _, key := range keys {
		if ed25519.Verify(key, data, sig) {
			return nil
		}
	}
	return fmt.Errorf("signature verification failed: no trusted key matched")
}
