// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !safe_values

package slog

// This file defines the most compact representation of Value.

import (
	"reflect"
	"unsafe"
)

// A Value can represent any Go value, but unlike type any,
// it can represent most small values without an allocation.
// The zero Value corresponds to nil.
type Value struct {
	// num holds the value for Kinds Int64, Uint64, Float64, Bool and Duration,
	// the string length for StringKind, and nanoseconds since the epoch for TimeKind.
	num uint64
	// If any is of type Kind, then the value is in num as described above.
	// If any is of type *time.Location, then the Kind is Time and time.Time value
	// can be constructed from the Unix nanos in num and the location (monotonic time
	// is not preserved).
	// If any is of type stringptr, then the Kind is String and the string value
	// consists of the length in num and the pointer in any.
	// Otherwise, the Kind is Any and any is the value.
	// (This implies that Attrs cannot store values of type Kind, *time.Location
	// or stringptr.)
	any any
}

type (
	stringptr unsafe.Pointer // used in Value.any when the Value is a string
	groupptr  unsafe.Pointer // used in Value.any when the Value is a []Attr
)

// Kind returns the Value's Kind.
func (v Value) Kind() Kind {
	switch x := v.any.(type) {
	case Kind:
		return x
	case stringptr:
		return StringKind
	case timeLocation:
		return TimeKind
	case groupptr:
		return GroupKind
	case LogValuer:
		return LogValuerKind
	case kind: // a kind is just a wrapper for a Kind
		return AnyKind
	default:
		return AnyKind
	}
}

// String returns a new Value for a string.
func StringValue(value string) Value {
	hdr := (*reflect.StringHeader)(unsafe.Pointer(&value))
	return Value{num: uint64(hdr.Len), any: stringptr(hdr.Data)}
}

func (v Value) str() string {
	var s string
	hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
	hdr.Data = uintptr(v.any.(stringptr))
	hdr.Len = int(v.num)
	return s
}

// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
// the methods Int64, Float64, and so on, which panic if the Value is of the
// wrong kind, String never panics.
func (v Value) String() string {
	if sp, ok := v.any.(stringptr); ok {
		// Inlining this code makes a huge difference.
		var s string
		hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
		hdr.Data = uintptr(sp)
		hdr.Len = int(v.num)
		return s
	}
	var buf []byte
	return string(v.append(buf))
}

func groupValue(as []Attr) Value {
	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&as))
	return Value{num: uint64(hdr.Len), any: groupptr(hdr.Data)}
}

// Group returns the Value's value as a []Attr.
// It panics if the Value's Kind is not GroupKind.
func (v Value) group() []Attr {
	if sp, ok := v.any.(groupptr); ok {
		return unsafe.Slice((*Attr)(sp), v.num)
	}
	panic("Group: bad kind")
}

func (v Value) uncheckedGroup() []Attr {
	return unsafe.Slice((*Attr)(v.any.(groupptr)), v.num)
}
