package systemtables

import (
	"crypto/rand"
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"strings"
)

const (
	hostIDNamespaceUUID       = "b3b7c2a3-9f3e-4d85-8d10-5f8e5a0a1f6e"
	schemaObjectNamespaceUUID = "3c1b6c64-6a9e-4b2e-9c3e-7b0d4b3b6a2f"
)

func uuidV5(namespaceUUID, name string) (string, error) {
	ns, err := parseUUIDBytes(namespaceUUID)
	if err != nil {
		return "", err
	}
	sum := sha1.Sum(append(ns[:], []byte(name)...))
	return formatUUIDBytes(uuidFromHash(sum[:])), nil
}

func uuidV4() (string, error) {
	var out [16]byte
	if _, err := rand.Read(out[:]); err != nil {
		return "", fmt.Errorf("uuidv4 random read: %w", err)
	}
	out[6] = (out[6] & 0x0f) | 0x40
	out[8] = (out[8] & 0x3f) | 0x80
	return formatUUIDBytes(out), nil
}

func uuidFromHash(hash []byte) [16]byte {
	var out [16]byte
	copy(out[:], hash)
	out[6] = (out[6] & 0x0f) | 0x50
	out[8] = (out[8] & 0x3f) | 0x80
	return out
}

func parseUUIDBytes(value string) ([16]byte, error) {
	var out [16]byte
	clean := strings.ReplaceAll(value, "-", "")
	if len(clean) != 32 {
		return out, fmt.Errorf("invalid UUID length: %d", len(clean))
	}
	decoded, err := hex.DecodeString(clean)
	if err != nil {
		return out, fmt.Errorf("invalid UUID value: %w", err)
	}
	copy(out[:], decoded)
	return out, nil
}

func formatUUIDBytes(value [16]byte) string {
	var buf [36]byte
	hex.Encode(buf[0:8], value[0:4])
	buf[8] = '-'
	hex.Encode(buf[9:13], value[4:6])
	buf[13] = '-'
	hex.Encode(buf[14:18], value[6:8])
	buf[18] = '-'
	hex.Encode(buf[19:23], value[8:10])
	buf[23] = '-'
	hex.Encode(buf[24:36], value[10:16])
	return string(buf[:])
}
