// Copyright 2009 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.

// Reflection library.
// Handling values.

package reflect

import (
	"reflect";
	"unsafe";
)

// Addr is shorthand for unsafe.Pointer and is used to represent the address of Values.
type Addr unsafe.Pointer

func equalType(a, b Type) bool {
	return a.String() == b.String()
}

// Value is the generic interface to reflection values.  Once its Kind is known,
// such as BoolKind, the Value can be narrowed to the appropriate, more
// specific interface, such as BoolValue.  Such narrowed values still implement
// the Value interface.
type Value interface {
	// The kind of thing described: ArrayKind, BoolKind, etc.
	Kind()	int;
	// The reflection Type of the value.
	Type()	Type;
	// The address of the value.
	Addr()	Addr;
	// The value itself is the dynamic value of an empty interface.
	Interface()	interface {};
}

func NewValue(e interface{}) Value;

// commonValue fields and functionality for all values

type commonValue struct {
	kind	int;
	typ	Type;
	addr	Addr;
}

func (c *commonValue) Kind() int {
	return c.kind
}

func (c *commonValue) Type() Type {
	return c.typ
}

func (c *commonValue) Addr() Addr {
	return c.addr
}

func (c *commonValue) Interface() interface {} {
	var i interface {};
	if c.typ.Size() > 8 {	// TODO(rsc): how do we know it is 8?
		i = sys.Unreflect(uint64(uintptr(c.addr)), c.typ.String(), true);
	} else {
		if uintptr(c.addr) == 0 {
			panicln("reflect: address 0 for", c.typ.String());
		}
		i = sys.Unreflect(uint64(uintptr(*(*Addr)(c.addr))), c.typ.String(), false);
	}
	return i;
}

func newValueAddr(typ Type, addr Addr) Value

type creatorFn func(typ Type, addr Addr) Value


// -- Missing

// MissingValue represents a value whose type is not known. It usually
// indicates an error.
type MissingValue interface {
	Value;
}

type missingValueStruct struct {
	commonValue
}

func missingCreator(typ Type, addr Addr) Value {
	return &missingValueStruct{ commonValue{MissingKind, typ, addr} }
}

// -- Int

// IntValue represents an int value.
type IntValue interface {
	Value;
	Get()	int;	// Get the underlying int.
	Set(int);	// Set the underlying int.
}

type intValueStruct struct {
	commonValue
}

func intCreator(typ Type, addr Addr) Value {
	return &intValueStruct{ commonValue{IntKind, typ, addr} }
}

func (v *intValueStruct) Get() int {
	return *(*int)(v.addr)
}

func (v *intValueStruct) Set(i int) {
	*(*int)(v.addr) = i
}

// -- Int8

// Int8Value represents an int8 value.
type Int8Value interface {
	Value;
	Get()	int8;	// Get the underlying int8.
	Set(int8);	// Set the underlying int8.
}

type int8ValueStruct struct {
	commonValue
}

func int8Creator(typ Type, addr Addr) Value {
	return &int8ValueStruct{ commonValue{Int8Kind, typ, addr} }
}

func (v *int8ValueStruct) Get() int8 {
	return *(*int8)(v.addr)
}

func (v *int8ValueStruct) Set(i int8) {
	*(*int8)(v.addr) = i
}

// -- Int16

// Int16Value represents an int16 value.
type Int16Value interface {
	Value;
	Get()	int16;	// Get the underlying int16.
	Set(int16);	// Set the underlying int16.
}

type int16ValueStruct struct {
	commonValue
}

func int16Creator(typ Type, addr Addr) Value {
	return &int16ValueStruct{ commonValue{Int16Kind, typ, addr} }
}

func (v *int16ValueStruct) Get() int16 {
	return *(*int16)(v.addr)
}

func (v *int16ValueStruct) Set(i int16) {
	*(*int16)(v.addr) = i
}

// -- Int32

// Int32Value represents an int32 value.
type Int32Value interface {
	Value;
	Get()	int32;	// Get the underlying int32.
	Set(int32);	// Set the underlying int32.
}

type int32ValueStruct struct {
	commonValue
}

func int32Creator(typ Type, addr Addr) Value {
	return &int32ValueStruct{ commonValue{Int32Kind, typ, addr} }
}

func (v *int32ValueStruct) Get() int32 {
	return *(*int32)(v.addr)
}

func (v *int32ValueStruct) Set(i int32) {
	*(*int32)(v.addr) = i
}

// -- Int64

// Int64Value represents an int64 value.
type Int64Value interface {
	Value;
	Get()	int64;	// Get the underlying int64.
	Set(int64);	// Set the underlying int64.
}

type int64ValueStruct struct {
	commonValue
}

func int64Creator(typ Type, addr Addr) Value {
	return &int64ValueStruct{ commonValue{Int64Kind, typ, addr} }
}

func (v *int64ValueStruct) Get() int64 {
	return *(*int64)(v.addr)
}

func (v *int64ValueStruct) Set(i int64) {
	*(*int64)(v.addr) = i
}

// -- Uint

// UintValue represents a uint value.
type UintValue interface {
	Value;
	Get()	uint;	// Get the underlying uint.
	Set(uint);	// Set the underlying uint.
}

type uintValueStruct struct {
	commonValue
}

func uintCreator(typ Type, addr Addr) Value {
	return &uintValueStruct{ commonValue{UintKind, typ, addr} }
}

func (v *uintValueStruct) Get() uint {
	return *(*uint)(v.addr)
}

func (v *uintValueStruct) Set(i uint) {
	*(*uint)(v.addr) = i
}

// -- Uint8

// Uint8Value represents a uint8 value.
type Uint8Value interface {
	Value;
	Get()	uint8;	// Get the underlying uint8.
	Set(uint8);	// Set the underlying uint8.
}

type uint8ValueStruct struct {
	commonValue
}

func uint8Creator(typ Type, addr Addr) Value {
	return &uint8ValueStruct{ commonValue{Uint8Kind, typ, addr} }
}

func (v *uint8ValueStruct) Get() uint8 {
	return *(*uint8)(v.addr)
}

func (v *uint8ValueStruct) Set(i uint8) {
	*(*uint8)(v.addr) = i
}

// -- Uint16

// Uint16Value represents a uint16 value.
type Uint16Value interface {
	Value;
	Get()	uint16;	// Get the underlying uint16.
	Set(uint16);	// Set the underlying uint16.
}

type uint16ValueStruct struct {
	commonValue
}

func uint16Creator(typ Type, addr Addr) Value {
	return &uint16ValueStruct{ commonValue{Uint16Kind, typ, addr} }
}

func (v *uint16ValueStruct) Get() uint16 {
	return *(*uint16)(v.addr)
}

func (v *uint16ValueStruct) Set(i uint16) {
	*(*uint16)(v.addr) = i
}

// -- Uint32

// Uint32Value represents a uint32 value.
type Uint32Value interface {
	Value;
	Get()	uint32;	// Get the underlying uint32.
	Set(uint32);	// Set the underlying uint32.
}

type uint32ValueStruct struct {
	commonValue
}

func uint32Creator(typ Type, addr Addr) Value {
	return &uint32ValueStruct{ commonValue{Uint32Kind, typ, addr} }
}

func (v *uint32ValueStruct) Get() uint32 {
	return *(*uint32)(v.addr)
}

func (v *uint32ValueStruct) Set(i uint32) {
	*(*uint32)(v.addr) = i
}

// -- Uint64

// Uint64Value represents a uint64 value.
type Uint64Value interface {
	Value;
	Get()	uint64;	// Get the underlying uint64.
	Set(uint64);	// Set the underlying uint64.
}

type uint64ValueStruct struct {
	commonValue
}

func uint64Creator(typ Type, addr Addr) Value {
	return &uint64ValueStruct{ commonValue{Uint64Kind, typ, addr} }
}

func (v *uint64ValueStruct) Get() uint64 {
	return *(*uint64)(v.addr)
}

func (v *uint64ValueStruct) Set(i uint64) {
	*(*uint64)(v.addr) = i
}

// -- Uintptr

// UintptrValue represents a uintptr value.
type UintptrValue interface {
	Value;
	Get()	uintptr;	// Get the underlying uintptr.
	Set(uintptr);	// Set the underlying uintptr.
}

type uintptrValueStruct struct {
	commonValue
}

func uintptrCreator(typ Type, addr Addr) Value {
	return &uintptrValueStruct{ commonValue{UintptrKind, typ, addr} }
}

func (v *uintptrValueStruct) Get() uintptr {
	return *(*uintptr)(v.addr)
}

func (v *uintptrValueStruct) Set(i uintptr) {
	*(*uintptr)(v.addr) = i
}

// -- Float

// FloatValue represents a float value.
type FloatValue interface {
	Value;
	Get()	float;	// Get the underlying float.
	Set(float);	// Get the underlying float.
}

type floatValueStruct struct {
	commonValue
}

func floatCreator(typ Type, addr Addr) Value {
	return &floatValueStruct{ commonValue{FloatKind, typ, addr} }
}

func (v *floatValueStruct) Get() float {
	return *(*float)(v.addr)
}

func (v *floatValueStruct) Set(f float) {
	*(*float)(v.addr) = f
}

// -- Float32

// Float32Value represents a float32 value.
type Float32Value interface {
	Value;
	Get()	float32;	// Get the underlying float32.
	Set(float32);	// Get the underlying float32.
}

type float32ValueStruct struct {
	commonValue
}

func float32Creator(typ Type, addr Addr) Value {
	return &float32ValueStruct{ commonValue{Float32Kind, typ, addr} }
}

func (v *float32ValueStruct) Get() float32 {
	return *(*float32)(v.addr)
}

func (v *float32ValueStruct) Set(f float32) {
	*(*float32)(v.addr) = f
}

// -- Float64

// Float64Value represents a float64 value.
type Float64Value interface {
	Value;
	Get()	float64;	// Get the underlying float64.
	Set(float64);	// Get the underlying float64.
}

type float64ValueStruct struct {
	commonValue
}

func float64Creator(typ Type, addr Addr) Value {
	return &float64ValueStruct{ commonValue{Float64Kind, typ, addr} }
}

func (v *float64ValueStruct) Get() float64 {
	return *(*float64)(v.addr)
}

func (v *float64ValueStruct) Set(f float64) {
	*(*float64)(v.addr) = f
}

// -- String

// StringValue represents a string value.
type StringValue interface {
	Value;
	Get()	string;	// Get the underlying string value.
	Set(string);	// Set the underlying string value.
}

type stringValueStruct struct {
	commonValue
}

func stringCreator(typ Type, addr Addr) Value {
	return &stringValueStruct{ commonValue{StringKind, typ, addr} }
}

func (v *stringValueStruct) Get() string {
	return *(*string)(v.addr)
}

func (v *stringValueStruct) Set(s string) {
	*(*string)(v.addr) = s
}

// -- Bool

// BoolValue represents a bool value.
type BoolValue interface {
	Value;
	Get()	bool;	// Get the underlying bool value.
	Set(bool);	// Set the underlying bool value.
}

type boolValueStruct struct {
	commonValue
}

func boolCreator(typ Type, addr Addr) Value {
	return &boolValueStruct{ commonValue{BoolKind, typ, addr} }
}

func (v *boolValueStruct) Get() bool {
	return *(*bool)(v.addr)
}

func (v *boolValueStruct) Set(b bool) {
	*(*bool)(v.addr) = b
}

// -- Pointer

// PtrValue represents a pointer value.
type PtrValue interface {
	Value;
	Sub()	Value;	// The Value pointed to.
	Get()	Addr;	// Get the address stored in the pointer.
	SetSub(Value);	// Set the the pointed-to Value.
}

type ptrValueStruct struct {
	commonValue
}

func (v *ptrValueStruct) Get() Addr {
	return *(*Addr)(v.addr)
}

func (v *ptrValueStruct) Sub() Value {
	return newValueAddr(v.typ.(PtrType).Sub(), v.Get());
}

func (v *ptrValueStruct) SetSub(subv Value) {
	a := v.typ.(PtrType).Sub();
	b := subv.Type();
	if !equalType(a, b) {
		panicln("reflect: incompatible types in PtrValue.SetSub:",
			a.String(), b.String());
	}
	*(*Addr)(v.addr) = subv.Addr();
}

func ptrCreator(typ Type, addr Addr) Value {
	return &ptrValueStruct{ commonValue{PtrKind, typ, addr} };
}

// -- Array
// Slices and arrays are represented by the same interface.

// ArrayValue represents an array or slice value.
type ArrayValue interface {
	Value;
	IsSlice()	bool;	// Is this a slice (true) or array (false)?
	Len()	int;	// The length of the array/slice.
	Cap() int;	// The capacity of the array/slice (==Len() for arrays).
	Elem(i int)	Value;	// The Value of the i'th element.
	SetLen(len int);	// Set the length; slice only.
	Set(src ArrayValue);	// Set the underlying Value; slice only for src and dest both.
	CopyFrom(src ArrayValue, n int)	// Copy the elements from src; lengths must match.
}

func copyArray(dst ArrayValue, src ArrayValue, n int);

/*
	Run-time representation of slices looks like this:
		struct	Slice {
			byte*	array;		// actual data
			uint32	nel;		// number of elements
			uint32	cap;
		};
*/
type runtimeSlice struct {
	data	Addr;
	len	uint32;
	cap	uint32;
}

type sliceValueStruct struct {
	commonValue;
	elemtype	Type;
	elemsize	int;
	slice *runtimeSlice;
}

func (v *sliceValueStruct) IsSlice() bool {
	return true
}

func (v *sliceValueStruct) Len() int {
	return int(v.slice.len);
}

func (v *sliceValueStruct) Cap() int {
	return int(v.slice.cap);
}

func (v *sliceValueStruct) SetLen(len int) {
	if len > v.Cap() {
		panicln("reflect: sliceValueStruct.SetLen", len, v.Cap());
	}
	v.slice.len = uint32(len);
}

func (v *sliceValueStruct) Set(src ArrayValue) {
	if !src.IsSlice() {
		panic("can't set slice from array");
	}
	s := src.(*sliceValueStruct);
	if !equalType(v.typ, s.typ) {
		panicln("incompatible types in ArrayValue.Set()");
	}
	*v.slice = *s.slice;
}

func (v *sliceValueStruct) Elem(i int) Value {
	data_uint := uintptr(v.slice.data) + uintptr(i * v.elemsize);
	return newValueAddr(v.elemtype, Addr(data_uint));
}

func (v *sliceValueStruct) CopyFrom(src ArrayValue, n int) {
	copyArray(v, src, n);
}

type arrayValueStruct struct {
	commonValue;
	elemtype	Type;
	elemsize	int;
	len	int;
}

func (v *arrayValueStruct) IsSlice() bool {
	return false
}

func (v *arrayValueStruct) Len() int {
	return v.len
}

func (v *arrayValueStruct) Cap() int {
	return v.len
}

func (v *arrayValueStruct) SetLen(len int) {
	panicln("can't set len of array");
}

func (v *arrayValueStruct) Set(src ArrayValue) {
	panicln("can't set array");
}

func (v *arrayValueStruct) Elem(i int) Value {
	data_uint := uintptr(v.addr) + uintptr(i * v.elemsize);
	return newValueAddr(v.elemtype, Addr(data_uint));
	return nil
}

func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) {
	copyArray(v, src, n);
}

func arrayCreator(typ Type, addr Addr) Value {
	arraytype := typ.(ArrayType);
	if arraytype.IsSlice() {
		v := new(sliceValueStruct);
		v.kind = ArrayKind;
		v.addr = addr;
		v.typ = typ;
		v.elemtype = arraytype.Elem();
		v.elemsize = v.elemtype.Size();
		v.slice = (*runtimeSlice)(addr);
		return v;
	}
	v := new(arrayValueStruct);
	v.kind = ArrayKind;
	v.addr = addr;
	v.typ = typ;
	v.elemtype = arraytype.Elem();
	v.elemsize = v.elemtype.Size();
	v.len = arraytype.Len();
	return v;
}

// -- Map	TODO: finish and test

// MapValue represents a map value.
// Its implementation is incomplete.
type MapValue interface {
	Value;
	Len()	int;	// The number of elements; currently always returns 0.
	Elem(key Value)	Value;	// The value indexed by key; unimplemented.
}

type mapValueStruct struct {
	commonValue
}

func mapCreator(typ Type, addr Addr) Value {
	return &mapValueStruct{ commonValue{MapKind, typ, addr} }
}

func (v *mapValueStruct) Len() int {
	return 0	// TODO: probably want this to be dynamic
}

func (v *mapValueStruct) Elem(key Value) Value {
	panic("map value element");
	return nil
}

// -- Chan

// ChanValue represents a chan value.
// Its implementation is incomplete.
type ChanValue interface {
	Value;
}

type chanValueStruct struct {
	commonValue
}

func chanCreator(typ Type, addr Addr) Value {
	return &chanValueStruct{ commonValue{ChanKind, typ, addr} }
}

// -- Struct

// StructValue represents a struct value.
type StructValue interface {
	Value;
	Len()	int;	// The number of fields.
	Field(i int)	Value;	// The Value of field i.
}

type structValueStruct struct {
	commonValue;
	field	[]Value;
}

func (v *structValueStruct) Len() int {
	return len(v.field)
}

func (v *structValueStruct) Field(i int) Value {
	return v.field[i]
}

func structCreator(typ Type, addr Addr) Value {
	t := typ.(StructType);
	nfield := t.Len();
	v := &structValueStruct{ commonValue{StructKind, typ, addr}, make([]Value, nfield) };
	for i := 0; i < nfield; i++ {
		name, ftype, str, offset := t.Field(i);
		addr_uint := uintptr(addr) + uintptr(offset);
		v.field[i] = newValueAddr(ftype, Addr(addr_uint));
	}
	v.typ = typ;
	return v;
}

// -- Interface

// InterfaceValue represents an interface value.
type InterfaceValue interface {
	Value;
	Get()	interface {};	// Get the underlying interface{} value.
	Value() Value;
}

type interfaceValueStruct struct {
	commonValue
}

func (v *interfaceValueStruct) Get() interface{} {
	return *(*interface{})(v.addr)
}

func (v *interfaceValueStruct) Value() Value {
	i := v.Get();
	if i == nil {
		return nil;
	}
	return NewValue(i);
}

func interfaceCreator(typ Type, addr Addr) Value {
	return &interfaceValueStruct{ commonValue{InterfaceKind, typ, addr} }
}

// -- Func


// FuncValue represents a func value.
// Its implementation is incomplete.
type FuncValue interface {
	Value;
	Get()	Addr;	// The address of the function.
}

type funcValueStruct struct {
	commonValue
}

func (v *funcValueStruct) Get() Addr {
	return *(*Addr)(v.addr)
}

func funcCreator(typ Type, addr Addr) Value {
	return &funcValueStruct{ commonValue{FuncKind, typ, addr} }
}

var creator = map[int] creatorFn {
	MissingKind : missingCreator,
	IntKind : intCreator,
	Int8Kind : int8Creator,
	Int16Kind : int16Creator,
	Int32Kind : int32Creator,
	Int64Kind : int64Creator,
	UintKind : uintCreator,
	Uint8Kind : uint8Creator,
	Uint16Kind : uint16Creator,
	Uint32Kind : uint32Creator,
	Uint64Kind : uint64Creator,
	UintptrKind : uintptrCreator,
	FloatKind : floatCreator,
	Float32Kind : float32Creator,
	Float64Kind : float64Creator,
	StringKind : stringCreator,
	BoolKind : boolCreator,
	PtrKind : ptrCreator,
	ArrayKind : arrayCreator,
	MapKind : mapCreator,
	ChanKind : chanCreator,
	StructKind : structCreator,
	InterfaceKind : interfaceCreator,
	FuncKind : funcCreator,
}

var typecache = make(map[string] Type);

func newValueAddr(typ Type, addr Addr) Value {
	c, ok := creator[typ.Kind()];
	if !ok {
		panicln("no creator for type" , typ.Kind());
	}
	return c(typ, addr);
}

// NewInitValue creates a new, zero-initialized Value for the specified Type.
func NewInitValue(typ Type) Value {
	// Some values cannot be made this way.
	switch typ.Kind() {
	case ArrayKind:
		if typ.(ArrayType).IsSlice() {
			return nil
		}
	}
	size := typ.Size();
	if size == 0 {
		size = 1;
	}
	data := make([]uint8, size);
	return newValueAddr(typ, Addr(&data[0]));
}

// NewSliceValue creates a new, zero-initialized slice value (ArrayValue) for the specified
// slice type (ArrayType), length, and capacity.
func NewSliceValue(typ ArrayType, len, cap int) ArrayValue {
	if !typ.IsSlice() {
		return nil
	}

	array := new(runtimeSlice);
	size := typ.Elem().Size() * cap;
	if size == 0 {
		size = 1;
	}
	data := make([]uint8, size);
	array.data = Addr(&data[0]);
	array.len = uint32(len);
	array.cap = uint32(cap);

	return newValueAddr(typ, Addr(array)).(ArrayValue);
}

// Works on both slices and arrays
func copyArray(dst ArrayValue, src ArrayValue, n int) {
	if n == 0 {
		return
	}
	dt := dst.Type().(ArrayType).Elem();
	st := src.Type().(ArrayType).Elem();
	if !equalType(dt, st) {
		panicln("reflect: incompatible types in CopyArray:",
			dt.String(), st.String());
	}
	if n < 0 || n > dst.Len() || n > src.Len() {
		panicln("reflect: CopyArray: invalid count", n);
	}
	dstp := uintptr(dst.Elem(0).Addr());
	srcp := uintptr(src.Elem(0).Addr());
	end := uintptr(n)*uintptr(dt.Size());
	if end % 8 == 0 {
		for i := uintptr(0); i < end; i += 8{
			di := Addr(dstp + i);
			si := Addr(srcp + i);
			*(*uint64)(di) = *(*uint64)(si);
		}
	} else {
		for i := uintptr(0); i < end; i++ {
			di := Addr(dstp + i);
			si := Addr(srcp + i);
			*(*byte)(di) = *(*byte)(si);
		}
	}
}

// NewValue creates a new Value from the interface{} object provided.
func NewValue(e interface {}) Value {
	value, typestring, indir := sys.Reflect(e);
	typ, ok := typecache[typestring];
	if !ok {
		typ = ParseTypeString("", typestring);
		typecache[typestring] = typ;
	}

	if indir {
		// Content of interface is a pointer.
		return newValueAddr(typ, Addr(uintptr(value)));
	}

	// Content of interface is a value;
	// need a permanent copy to take its address.
	ap := new(uint64);
	*ap = value;
	return newValueAddr(typ, Addr(ap));
}

// Indirect indirects one level through a value, if it is a pointer.
// If not a pointer, the value is returned unchanged.
// Useful when walking arbitrary data structures.
func Indirect(v Value) Value {
	if v.Kind() == PtrKind {
		p := v.(PtrValue);
		if p.Get() == nil {
			return nil
		}
		v = p.Sub()
	}
	return v
}
